From c5bb53846299f13867fa72d798fea5e7c9cfc5a8 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 01/75] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#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. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From 3c7d3887e161606aaf826c8ba710770b04f05edb Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 24 Jul 2019 20:16:22 -0700 Subject: [PATCH 02/75] hans comments --- docs/core/transactions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 69a260d3edce..60c2c9f9ac20 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#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. @@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin **Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. -Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. @@ -81,4 +81,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 41e922cd99d2d755e37f105472d8a52fb92bdfce Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 03/75] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#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. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From 1e70aafcd5ae63879498c5639ade228cfbef9e09 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 10 Aug 2019 16:56:47 -0400 Subject: [PATCH 04/75] gautier comments --- docs/core/transactions.md | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 43fb49988e36..a2cd7bb494ee 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module through the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) 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. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../building-modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../building-modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/interfaces.md#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. @@ -47,19 +47,15 @@ When users interact with the application's interfaces, they invoke the underlyin Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves -The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface has five required functions. - -* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. -* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. -* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. -* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. -* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. +To learn more about messages, click [here](../building-modules/messages-and-queries.md#messages). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. ## Transaction Generation -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). +Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: @@ -81,4 +77,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). +The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 16d78da8b0e5e92bb27deb27f66d53e3fee6d690 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 20 May 2019 14:08:56 +0200 Subject: [PATCH 05/75] consolidate intro --- docs/intro/README.md | 15 +++++------ docs/intro/sdk-app-architecture.md | 26 +++++++++---------- docs/intro/why-app-specific.md | 41 +++++++++++++++--------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/intro/README.md b/docs/intro/README.md index 9df4e13e443c..e753330be21b 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,13 +18,12 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) - diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 94007a2742dc..a420fe627c33 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 1b160429f6eb..ce454383711c 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,40 +40,39 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. - Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. From 66dd67509b41365516d2ec16fab2da4dc21c2e26 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 28 May 2019 17:32:29 +0200 Subject: [PATCH 06/75] querier --- docs/concepts/amino.md | 3 +++ docs/concepts/genesis.md | 3 +++ docs/concepts/handler.md | 1 + docs/concepts/keeper.md | 0 docs/concepts/modules.md | 3 +++ docs/concepts/querier.md | 3 +++ docs/core/node.md | 2 +- docs/intro/README.md | 2 +- 8 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/amino.md create mode 100644 docs/concepts/genesis.md create mode 100644 docs/concepts/handler.md create mode 100644 docs/concepts/keeper.md create mode 100644 docs/concepts/modules.md create mode 100644 docs/concepts/querier.md diff --git a/docs/concepts/amino.md b/docs/concepts/amino.md new file mode 100644 index 000000000000..8113f63e9630 --- /dev/null +++ b/docs/concepts/amino.md @@ -0,0 +1,3 @@ +# Amnio Encoding + +TODO \ No newline at end of file diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md new file mode 100644 index 000000000000..5e3dbd31dcad --- /dev/null +++ b/docs/concepts/genesis.md @@ -0,0 +1,3 @@ +# Genesis File + +TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md new file mode 100644 index 000000000000..f8fc820df8de --- /dev/null +++ b/docs/concepts/handler.md @@ -0,0 +1 @@ +# Handlers \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md new file mode 100644 index 000000000000..cfd71f817963 --- /dev/null +++ b/docs/concepts/modules.md @@ -0,0 +1,3 @@ +# SDK Modules + +Todo: Intro concept docs on modules \ No newline at end of file diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md new file mode 100644 index 000000000000..3afa9f0cc308 --- /dev/null +++ b/docs/concepts/querier.md @@ -0,0 +1,3 @@ +# Queriers + +TODO \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 85c6152542ad..36fe12602d0d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## `main` function +## main function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e753330be21b..e676fd179b16 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). From 6d1df2ef4e246fda17d46eded014d7b32073cba5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:10:54 +0200 Subject: [PATCH 07/75] workiiiing --- docs/.vuepress/config.js | 3 +- docs/concepts/app-anatomy.md | 212 +++++++++++++++++++++++++++++++++ docs/intro/why-app-specific.md | 2 +- 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/app-anatomy.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9ee6a31059c5..d8756aae2385 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,7 +31,8 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design" + "/intro/sdk-design", + "intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md new file mode 100644 index 000000000000..346b35abab80 --- /dev/null +++ b/docs/concepts/app-anatomy.md @@ -0,0 +1,212 @@ +# Anatomy of an SDK Application + +## Pre-requisite reading + +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) +- [Cosmos SDK design overview](../intro/sdk-design.md) + +## Synopsis + +This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. + +- [Node Client](#node-client) +- [Core Application File](#core-application-file) +- [Modules](#modules) +- [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) + +The core parts listed above will generally translate to the following directory tree: + +``` +./app +├── cmd/ +│ ├── appd +│ └── appcli +├── app.go +├── x/ +│ ├── auth +│ └── bank +├── Gopkg.toml +└── Makefile +``` + +## Node Client (Daemon) + +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. + +``` + ^ +-------------------------------+ ^ + | | | | + | | State+machine = Application | | + | | | | Built with Cosmos SDK + | | ^ + | | + | +----------- | ABCI | ----------+ v + | | + v | ^ + | | | | +Blockchain Node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). + +To learn more about the `main.go` function, [click here](./node.md#main-function). + +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. + +The `start` command function primarily does three things: + +1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). + +To learn more about the `start` command, [click here](./node.md#start-command). + +## Core Application File + +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. + +### Type Definition of the Application + +The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: + +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. + +You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). + +### Constructor Function + +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: + +- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instanciate all the `keepers` defined in the application's `type`. +- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. +- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Return the application. + +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. + +You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). + +### InitChainer + +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). + +### Register Codec + +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. + +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. + +You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). + +## Modules + +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. + +To learn more about modules, [click here](./modules.md) + +### Message Types + +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md) + +### Handler + +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). + +The handler of a module is generally defined in a file called `handler.go` and consists of: + +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. + +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. + +To learn more about handlers, [click here](./handler.md). + +### Keeper + +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). + +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. + +The `keeper` type definition generally consists of: + +- **Key(s)** to the module's store(s) in the multistore. +- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. + +The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). + +To learn more about `keepers`, [click here](./keeper.md). + +### Querier + +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. + +The `Querier` of a module are defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](./querier.md). + +### Command-Line and REST Interfaces + +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. + +#### CLI + +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): + +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). + +To learn more about modules CLI, [click here](./module-interfaces.md#cli). + +#### REST + +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. + +See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). + +To learn more about modules REST interface, [click here](./module-interfaces.md#rest). + +## Application Interface + +Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. + +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: + +- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. + +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). + +To learn more about interfaces, [click here](./interfaces.md) + +## Dependencies and Makefile + + + +## Next + +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index ce454383711c..0873f87d0e4a 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -74,5 +74,5 @@ The fundamental issue here is that the governance of the application and the gov Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) - Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. +- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) From afbaba58e490008cd7baa176d2c31d973a30cddc Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 10 Jun 2019 15:13:41 +0200 Subject: [PATCH 08/75] refactor for new module interface --- docs/.vuepress/config.js | 2 +- docs/concepts/app-anatomy.md | 132 +++++++++++++++--------- docs/concepts/{amino.md => encoding.md} | 0 docs/concepts/fees-signature.md | 7 ++ docs/concepts/invariants.md | 5 + docs/concepts/modules.md | 7 +- 6 files changed, 105 insertions(+), 48 deletions(-) rename docs/concepts/{amino.md => encoding.md} (100%) create mode 100644 docs/concepts/fees-signature.md create mode 100644 docs/concepts/invariants.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d8756aae2385..602d20781420 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -32,7 +32,7 @@ module.exports = { "/intro/why-app-specific", "/intro/sdk-app-architecture", "/intro/sdk-design", - "intro/ocap" + "/intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 346b35abab80..1646e0f39e8a 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -28,16 +28,16 @@ The core parts listed above will generally translate to the following directory │ └── bank ├── Gopkg.toml └── Makefile -``` +``` -## Node Client (Daemon) +## Node Client -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` ^ +-------------------------------+ ^ | | | | - | | State+machine = Application | | + | | State-machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v @@ -55,73 +55,111 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: -1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). To learn more about the `start` command, [click here](./node.md#start-command). ## Core Application File -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. ### Type Definition of the Application The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). +You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). ### Constructor Function This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instanciate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. -- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. -- Set the application's [`initChainer`](#initchainer) and mount the stores. -- Return the application. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Mount the stores. +- Return the application. -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. + +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). + +### BeginBlocker and EndBlocker -You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. + +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. + +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. + +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) +### Application Module Interface + +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. + +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. + +To learn more about the application module interface, [click here](./modules.md#application-module-interface). + ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: + +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -To learn more about messages, [click here](./tx-msgs.md) +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md). ### Handler @@ -129,8 +167,8 @@ The `handler` refers to the part of the module responsible for processing the me The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. @@ -140,36 +178,38 @@ To learn more about handlers, [click here](./handler.md). `Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. The `keeper` type definition generally consists of: -- **Key(s)** to the module's store(s) in the multistore. +- **Key(s)** to the module's store(s) in the multistore. - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. + +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). To learn more about `keepers`, [click here](./keeper.md). -### Querier +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module are defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). ### Command-Line and REST Interfaces -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). @@ -181,7 +221,7 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- 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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). @@ -190,23 +230,23 @@ To learn more about modules REST interface, [click here](./module-interfaces.md# ## Application Interface -Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). To learn more about interfaces, [click here](./interfaces.md) -## Dependencies and Makefile +## Dependencies and Makefile ## Next -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/amino.md b/docs/concepts/encoding.md similarity index 100% rename from docs/concepts/amino.md rename to docs/concepts/encoding.md diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md new file mode 100644 index 000000000000..36982a97b5d8 --- /dev/null +++ b/docs/concepts/fees-signature.md @@ -0,0 +1,7 @@ +# Fees and Signatures + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md new file mode 100644 index 000000000000..18cd9ad6224f --- /dev/null +++ b/docs/concepts/invariants.md @@ -0,0 +1,5 @@ +# Invariants + +## What is an invariant + +## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md index cfd71f817963..5c65c4d89f92 100644 --- a/docs/concepts/modules.md +++ b/docs/concepts/modules.md @@ -1,3 +1,8 @@ # SDK Modules -Todo: Intro concept docs on modules \ No newline at end of file +Todo: Intro concept docs on modules + +## Application Module Interface + +## Module Manager + From a039341475901ea97d08bbbf048c566b58249839 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 16:09:21 +0200 Subject: [PATCH 09/75] karoly review --- docs/concepts/app-anatomy.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 1646e0f39e8a..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -75,8 +75,8 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -91,7 +91,10 @@ This function constructs a new application of the type defined above. It is [cal - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. - With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Set the remainer of application's parameters: + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. From dc97fb5b2fa3aa3444ba8170651c53c01363ba1f Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 17 Jun 2019 16:55:53 +0200 Subject: [PATCH 10/75] working on baseapp doc --- docs/concepts/baseapp_old.md | 128 +++++++++++++++++++++++++++++ docs/concepts/store.md | 8 ++ docs/core/baseapp_old.md | 151 +++++++++++++---------------------- 3 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 docs/concepts/baseapp_old.md create mode 100644 docs/concepts/store.md diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/concepts/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. diff --git a/docs/concepts/store.md b/docs/concepts/store.md new file mode 100644 index 000000000000..067eea3b79bd --- /dev/null +++ b/docs/concepts/store.md @@ -0,0 +1,8 @@ +# Store + +## Commit Multi Store + +## Database + +## Main Store + diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index c4f71f33f696..855b03cf1b55 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -1,128 +1,89 @@ # BaseApp -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Pre-requisite Reading -## Routing +- [Anatomy of an SDK application](./app-anatomy.md) +- [Lifecycle of an SDK transaction](./tx-lifecycle.md) -TODO +## Synopsis -## Transaction Life Cycle +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. +- [Introduction](#introduction) +- [Type Definition](#type-definition) +- [States and Modes](#states-and-modes) +- [Routing](#routing) +- [ABCI](#abci) +- [CheckTx](#abci-checktx) +- [DeliverTx](#abci-delivertx) +- [Commit](#abbci-commit) +- [Other ABCI Message](#other-abci-message) + + [Info](#info) + + [SetOption](#setoption) + + [Query](#query) + + [InitChain](#initchain) + + [BeginBlock](#beginblock) + + [EndBlock](#endblock) +- [Gas](#gas) -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. -### CheckTx +## Introduction -During the execution of `CheckTx`, only the AnteHandler is executed. +`baseapp` is an abstraction that implements the core of an SDK application, namely: -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. -### DeliverTx +The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. +```go +type app struct { + *bam.BaseApp // reference to baseapp + cdc *codec.Codec -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. + // list of application store keys -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. + // list of application keepers + // module manager +} +``` -## Other ABCI Messages +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. +## Type Definition -### Info -TODO complete description +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: -### SetOption -TODO complete description +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. +- -### Query -TODO complete description +## States and Modes -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description +## Routing -### EndBlock -TODO complete description +## ABCI -### Commit -TODO complete description +## ABCI - CheckTx +## ABCI - DeliverTx -## Gas Management +## ABCI - Commit -### Gas: InitChain +## Other ABCI Messages -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. +### Info -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. +### SetOption -### Gas: BeginBlock +### Query -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. +### InitChain -### Gas: DeliverTx +### BeginBlock -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. +### EndBlock -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. +## Gas \ No newline at end of file From 24570feb242331423084a37faf8ff02c27d15391 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:47:33 +0200 Subject: [PATCH 11/75] baseapp work --- docs/concepts/accounts-fees.md | 11 +++++ docs/concepts/app-anatomy.md | 4 +- docs/concepts/fees-signature.md | 7 --- docs/core/baseapp_old.md | 85 ++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 docs/concepts/accounts-fees.md delete mode 100644 docs/concepts/fees-signature.md diff --git a/docs/concepts/accounts-fees.md b/docs/concepts/accounts-fees.md new file mode 100644 index 000000000000..9f03e0eb033d --- /dev/null +++ b/docs/concepts/accounts-fees.md @@ -0,0 +1,11 @@ +# Accounts, Fees and Signatures + +## Accounts + +## AnteHandler + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 78d7b1eda675..177a84f19c7e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index 855b03cf1b55..c239272fcba3 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -11,7 +11,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) -- [States and Modes](#states-and-modes) +- [States](#states) - [Routing](#routing) - [ABCI](#abci) - [CheckTx](#abci-checktx) @@ -33,7 +33,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -54,26 +54,87 @@ Extending the application with `baseapp` gives the former access to all of `base ## Type Definition -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* + +First, the important parameters that are initialized during the initialization of the application: + +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. +- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. +- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. + +Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): + +- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). +- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). + +Finally, a few more important parameterd: + +- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). + +## States + +`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. + +### Main State + +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -## States and Modes +### Volatile States + +Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: + +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ## Routing -## ABCI +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. + +### Message Routing + +Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. + +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). + +### Query Routing + +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -## ABCI - CheckTx +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). -## ABCI - DeliverTx +## Main ABCI Messages -## ABCI - Commit + + +### CheckTx + +### DeliverTx + +## RunTx and RunMsg ## Other ABCI Messages +### Commit + ### Info ### SetOption @@ -84,6 +145,4 @@ The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/ba ### BeginBlock -### EndBlock - -## Gas \ No newline at end of file +### EndBlock \ No newline at end of file From 2c412ec7251bd1e774dcb63b73b197c6c4bc3036 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:59:31 +0200 Subject: [PATCH 12/75] reorg --- docs/{concepts => basics}/accounts-fees.md | 0 docs/basics/app-anatomy.md | 63 ++--- docs/building-modules/module-interfaces.md | 280 ++++++++++++++++++++- docs/concepts/app-anatomy.md | 4 +- docs/concepts/baseapp_old.md | 128 ---------- docs/concepts/genesis.md | 3 - docs/concepts/store.md | 8 - docs/core/baseapp_old.md | 148 ----------- docs/{concepts => modules}/handler.md | 0 docs/{concepts => modules}/invariants.md | 0 docs/{concepts => modules}/keeper.md | 0 docs/modules/module-interfaces.md | 5 + docs/{concepts => modules}/modules.md | 0 docs/{concepts => modules}/querier.md | 0 14 files changed, 319 insertions(+), 320 deletions(-) rename docs/{concepts => basics}/accounts-fees.md (100%) delete mode 100644 docs/concepts/baseapp_old.md delete mode 100644 docs/concepts/genesis.md delete mode 100644 docs/concepts/store.md delete mode 100644 docs/core/baseapp_old.md rename docs/{concepts => modules}/handler.md (100%) rename docs/{concepts => modules}/invariants.md (100%) rename docs/{concepts => modules}/keeper.md (100%) create mode 100644 docs/modules/module-interfaces.md rename docs/{concepts => modules}/modules.md (100%) rename docs/{concepts => modules}/querier.md (100%) diff --git a/docs/concepts/accounts-fees.md b/docs/basics/accounts-fees.md similarity index 100% rename from docs/concepts/accounts-fees.md rename to docs/basics/accounts-fees.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 15e1c9fc1e22..bca2c0c2774f 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -57,7 +57,7 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](../core/node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +87,17 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -105,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -117,13 +117,13 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). @@ -131,15 +131,22 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). @@ -148,9 +155,9 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). @@ -164,8 +171,8 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -189,9 +196,9 @@ The rest of the file defines the `keeper`'s methods, primarily getters and sette To learn more about `keepers`, [click here](../building-modules/keeper.md). -### Querier +### Querier -[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -232,9 +239,9 @@ Interfaces let end-users interact with full-node clients. This means querying da The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 744c439c67f2..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,9 +1,283 @@ # Module Interfaces +## Prerequisites + +* [Building Modules Intro](./intro.md) + +## Synopsis + +This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules will be included. + +- [CLI](#cli) + + [Transaction Commands](#tx-commands) + + [Query Commands](#query-commands) +- [REST](#rest) + + [Request Types](#request-types) + + [Request Handlers](#request-handlers) + + [Register Routes](#register-routes) + ## CLI -### Tx +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. + +### 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. Here is an example from the nameservice tutorial: + +```go +func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "buy-name [name] [amount]", + Short: "bid for existing name or claim new name", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) + + txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + + if err := cliCtx.EnsureAccountExists(); err != nil { + return err + } + + coins, err := sdk.ParseCoins(args[1]) + if err != nil { + return err + } + + msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress()) + err = msg.ValidateBasic() + if err != nil { + return err + } + + cliCtx.PrintResponse = true + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) + }, + } +} +``` + +This getter function creates the command for the Buy Name transaction. It does the following: + +- **`codec`**. The getter function takes in an application [`codec`](../core/encoding.md) as an argument and returns a reference to the `cobra.command`. Since a module is intended to be used by any application, the `codec` must be provided. +- **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. + + **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. + + **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 [`CLIContext`](./query-lifecycle.md#clicontext) 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 `CLIContext` 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()`. + + A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `CLIContext`. 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. + + +#### GetTxCmd + +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`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. + +```go +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Auth transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + txCmd.AddCommand( + GetMultiSignCommand(cdc), + GetSignCommand(cdc), + ) + return txCmd +} +``` + +### Query Commands + +[Queries](./messages-and-queries.md) 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: + +```go +func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "whois [name]", + Short: "Query whois info of name", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + name := args[0] + + res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil) + if err != nil { + fmt.Printf("could not resolve whois - %s \n", string(name)) + return nil + } + + var out nameservice.Whois + cdc.MustUnmarshalJSON(res, &out) + return cliCtx.PrintOutput(out) + }, + } +} + +``` + +This query returns the address that owns a particular name. 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. +- **`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 [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + + If applicable, the `CLIContext` 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 `CLIContext` parameters in this case because the query does not involve any information about the user. + + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. +- **Flags.** Add any [flags](#flags) to the command. + +#### GetQueryCmd + +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`](#gettxcmd) command. + +### Flags + +[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. + +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 example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. + +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") +``` + +The input provided for this flag - called `FlagFrom` is a string with the default value of `""` if none is provided. If the user asks for a description of this flag, the description will be printed. + +A flag can be marked as *required* so that an error is automatically thrown if the user does not provide a value: + +```go +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). + +## REST + +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. + +### Request Types + +Request types must be defined for all *transaction* requests. 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](https://cosmos.network/docs/tutorial/rest.html) module: + +```go +type buyNameReq struct { + BaseReq rest.BaseReq `json:"base_req"` + Name string `json:"name"` + Amount string `json:"amount"` + Buyer string `json:"buyer"` +} +``` + +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. + +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much [gas](../core/gas.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. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. + +Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): + +```go +func buyNameHandler(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req buyNameReq + + if !rest.ReadRESTReq(w, r, cdc, &req) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request") + return + } + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBaic(w) { + return + } + + addr, err := sdk.AccAddressFromBech32(req.Buyer) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + coins, err := sdk.ParseCoins(req.Amount) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + //create message + msg := nameservice.NewMsgBuyName(req.Name, coins, addr) + err = msg.ValidateBasic() + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, baseReq, []sdk.Msg{msg}) + + } +} +``` + +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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + +The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. + +The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. + +Here is a `registerRoutes` function with one query route example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/rest.html): + +``` go +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) { + // ResolveName Query + r.HandleFunc(fmt.Sprintf("/%s/names/{%s}", storeName, restName), resolveNameHandler(cdc, cliCtx, storeName)).Methods("GET") +} +``` + +A few things to note: + +* The router `r` has already been initialized by the application and is passed in here as an argument - this function is able to add on the nameservice module's routes onto any application's router. The application must also provide a [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) that the querier will need to process user requests and the application [`codec`](../core/encoding.md) for encoding and decoding application-specific types. +* `"/%s/names/{%s}", storeName, restName` is the url for the HTTP request. `storeName` is the name of the module, `restName` is a variable provided by the user to specify what kind of query they are making. +* `resolveNameHandler` is the query request handler defined by the module developer. It also takes the application `codec` and `CLIContext` passed in from the user side, as well as the `storeName`. +* `"GET"` is the HTTP Request method. As to be expected, queries are typically GET requests. Transactions are typically POST and PUT requests. + -### Query +## Next -## REST \ No newline at end of file +Read about the next topic in building modules. diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 177a84f19c7e..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md deleted file mode 100644 index c4f71f33f696..000000000000 --- a/docs/concepts/baseapp_old.md +++ /dev/null @@ -1,128 +0,0 @@ -# BaseApp - -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. - -## Routing - -TODO - -## Transaction Life Cycle - -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. - -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. - -### CheckTx - -During the execution of `CheckTx`, only the AnteHandler is executed. - -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. - -### DeliverTx - -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. - -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. - -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. - - -## Other ABCI Messages - -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. - -### Info -TODO complete description - -### SetOption -TODO complete description - -### Query -TODO complete description - -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description - -### EndBlock -TODO complete description - -### Commit -TODO complete description - - -## Gas Management - -### Gas: InitChain - -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. - -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. - -### Gas: BeginBlock - -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. - -### Gas: DeliverTx - -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. - -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/concepts/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/concepts/store.md b/docs/concepts/store.md deleted file mode 100644 index 067eea3b79bd..000000000000 --- a/docs/concepts/store.md +++ /dev/null @@ -1,8 +0,0 @@ -# Store - -## Commit Multi Store - -## Database - -## Main Store - diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md deleted file mode 100644 index c239272fcba3..000000000000 --- a/docs/core/baseapp_old.md +++ /dev/null @@ -1,148 +0,0 @@ -# BaseApp - -## Pre-requisite Reading - -- [Anatomy of an SDK application](./app-anatomy.md) -- [Lifecycle of an SDK transaction](./tx-lifecycle.md) - -## Synopsis - -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - -- [Introduction](#introduction) -- [Type Definition](#type-definition) -- [States](#states) -- [Routing](#routing) -- [ABCI](#abci) -- [CheckTx](#abci-checktx) -- [DeliverTx](#abci-delivertx) -- [Commit](#abbci-commit) -- [Other ABCI Message](#other-abci-message) - + [Info](#info) - + [SetOption](#setoption) - + [Query](#query) - + [InitChain](#initchain) - + [BeginBlock](#beginblock) - + [EndBlock](#endblock) -- [Gas](#gas) - - -## Introduction - -`baseapp` is an abstraction that implements the core of an SDK application, namely: - -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. - -The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: - -```go -type app struct { - *bam.BaseApp // reference to baseapp - cdc *codec.Codec - - // list of application store keys - - // list of application keepers - - // module manager -} -``` - -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. - -## Type Definition - -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. - -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* - -First, the important parameters that are initialized during the initialization of the application: - -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. -- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. -- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. -- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. - -Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - -- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). -- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). - -Finally, a few more important parameterd: - -- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). - -## States - -`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. - -### Main State - -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. - -``` -+--------+ +--------+ -| | | | -| S +----------------------------> | S' | -| | For each T in B: apply(T) | | -+--------+ +--------+ -``` - -The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. - -### Volatile States - -Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: - -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). -- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - -## Routing - -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. - -### Message Routing - -Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. - -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -### Query Routing - -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. - -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -## Main ABCI Messages - - - -### CheckTx - -### DeliverTx - -## RunTx and RunMsg - -## Other ABCI Messages - -### Commit - -### Info - -### SetOption - -### Query - -### InitChain - -### BeginBlock - -### EndBlock \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/modules/handler.md similarity index 100% rename from docs/concepts/handler.md rename to docs/modules/handler.md diff --git a/docs/concepts/invariants.md b/docs/modules/invariants.md similarity index 100% rename from docs/concepts/invariants.md rename to docs/modules/invariants.md diff --git a/docs/concepts/keeper.md b/docs/modules/keeper.md similarity index 100% rename from docs/concepts/keeper.md rename to docs/modules/keeper.md diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md new file mode 100644 index 000000000000..0cd27c895326 --- /dev/null +++ b/docs/modules/module-interfaces.md @@ -0,0 +1,5 @@ +# Module Interfaces + +## CLI + +## REST \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/modules/modules.md similarity index 100% rename from docs/concepts/modules.md rename to docs/modules/modules.md diff --git a/docs/concepts/querier.md b/docs/modules/querier.md similarity index 100% rename from docs/concepts/querier.md rename to docs/modules/querier.md From f783f03ebb3110b65f49854cdae6d705454af7b9 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 12:00:14 +0200 Subject: [PATCH 13/75] almost there --- docs/basics/accounts-fees.md | 2 +- docs/concepts/app-anatomy.md | 255 ------------------------------ docs/concepts/tx-msgs.md | 5 + docs/core/baseapp.md | 194 +++++++++++++---------- docs/modules/handler.md | 1 - docs/modules/invariants.md | 5 - docs/modules/keeper.md | 0 docs/modules/module-interfaces.md | 5 - docs/modules/modules.md | 8 - docs/modules/querier.md | 3 - 10 files changed, 115 insertions(+), 363 deletions(-) delete mode 100644 docs/concepts/app-anatomy.md create mode 100644 docs/concepts/tx-msgs.md delete mode 100644 docs/modules/handler.md delete mode 100644 docs/modules/invariants.md delete mode 100644 docs/modules/keeper.md delete mode 100644 docs/modules/module-interfaces.md delete mode 100644 docs/modules/modules.md delete mode 100644 docs/modules/querier.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md index 9f03e0eb033d..20fe1fb2dac8 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Signatures +# Accounts, Fees and Gas ## Accounts diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md deleted file mode 100644 index 78d7b1eda675..000000000000 --- a/docs/concepts/app-anatomy.md +++ /dev/null @@ -1,255 +0,0 @@ -# Anatomy of an SDK Application - -## Pre-requisite reading - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) - -## Synopsis - -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Intefaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ └── bank -├── Gopkg.toml -└── Makefile -``` - -## Node Client - -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. - -``` - ^ +-------------------------------+ ^ - | | | | - | | State-machine = Application | | - | | | | Built with Cosmos SDK - | | ^ + | | - | +----------- | ABCI | ----------+ v - | | + v | ^ - | | | | -Blockchain Node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](./node.md#main-function). - -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. - -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). - -To learn more about the `start` command, [click here](./node.md#start-command). - -## Core Application File - -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. - -### Type Definition of the Application - -The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: - -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). - -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). - -### Constructor Function - -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: - -- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. - -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. - -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). - -### InitChainer - -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. - -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. - -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). - -### BeginBlocker and EndBlocker - -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. - -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. - -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. - -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). - -### Register Codec - -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. - -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). - -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) - -## Modules - -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). - -### Message Types - -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: - -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. - -For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). - -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. - -To learn more about messages, [click here](./tx-msgs.md). - -### Handler - -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). - -The handler of a module is generally defined in a file called `handler.go` and consists of: - -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. - -To learn more about handlers, [click here](./handler.md). - -### Keeper - -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). - -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. - -The `keeper` type definition generally consists of: - -- **Key(s)** to the module's store(s) in the multistore. -- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. - -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). - -To learn more about `keepers`, [click here](./keeper.md). - -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module are defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](./querier.md). - -### Command-Line and REST Interfaces - -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. - -#### CLI - -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). - -To learn more about modules CLI, [click here](./module-interfaces.md#cli). - -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. -- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. - -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). - -## Application Interface - -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. - -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - -To learn more about interfaces, [click here](./interfaces.md) - -## Dependencies and Makefile - - - -## Next - -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md new file mode 100644 index 000000000000..fde1963e3c2a --- /dev/null +++ b/docs/concepts/tx-msgs.md @@ -0,0 +1,5 @@ +# Transactions and Messages + +## Transactions + +## Messages diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6c3d2dd9e506..7f8214b34e4c 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,21 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + + + + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +55,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +87,17 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. + +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. + +A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. + +## Constructor -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,7 +127,54 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(2) | | | + | | +----------------------+ | | +DeliverTx(tx3) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(3) | | | + +----------------------+ +----------------------+ +----------------------+ +Commit() | | | + v v v + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | + +----------------------+ | | | | + . . . + . . . + . . . + +``` + +``` + To perform stateful checks To execute state To answer queries + on received transactions transitions during DeliverTx about last-committed state + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | + +----------------------+ | | | | +CheckTx(tx1) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(1) | | | | | + +----------------------+ | | | | +CheckTx(tx2) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(2) | | | | | + +----------------------+ | | | | +CheckTx(tx3) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(3) | | | | | + +----------------------+ +----------------------+ | | +DeliverTx(tx1) | | | | + v v | | + +----------------------+ +----------------------+ | | + | | | DeliverState(t)(1) | | | + | | +----------------------+ | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -138,12 +192,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -159,13 +213,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -175,24 +229,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the 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). +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. 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). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -204,43 +258,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -248,13 +302,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -264,66 +318,36 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages ### InitChain -The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: - -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. -- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. - -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. +The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. ### BeginBlock -The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. - ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. - ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. - -### Query - -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). - -The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - -- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). - -## Next - -Learn more about [stores](./store.md). +### Query diff --git a/docs/modules/handler.md b/docs/modules/handler.md deleted file mode 100644 index f8fc820df8de..000000000000 --- a/docs/modules/handler.md +++ /dev/null @@ -1 +0,0 @@ -# Handlers \ No newline at end of file diff --git a/docs/modules/invariants.md b/docs/modules/invariants.md deleted file mode 100644 index 18cd9ad6224f..000000000000 --- a/docs/modules/invariants.md +++ /dev/null @@ -1,5 +0,0 @@ -# Invariants - -## What is an invariant - -## Invariant Registry \ No newline at end of file diff --git a/docs/modules/keeper.md b/docs/modules/keeper.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/modules/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/modules/modules.md b/docs/modules/modules.md deleted file mode 100644 index 5c65c4d89f92..000000000000 --- a/docs/modules/modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# SDK Modules - -Todo: Intro concept docs on modules - -## Application Module Interface - -## Module Manager - diff --git a/docs/modules/querier.md b/docs/modules/querier.md deleted file mode 100644 index 3afa9f0cc308..000000000000 --- a/docs/modules/querier.md +++ /dev/null @@ -1,3 +0,0 @@ -# Queriers - -TODO \ No newline at end of file From 653ada24d54e8d82db40fe0e3032cb0e7376e708 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:53:40 +0200 Subject: [PATCH 14/75] finish first draft --- docs/basics/accounts-fees.md | 11 ------- docs/basics/app-anatomy.md | 4 +-- docs/core/baseapp.md | 63 ++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 33 deletions(-) delete mode 100644 docs/basics/accounts-fees.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md deleted file mode 100644 index 20fe1fb2dac8..000000000000 --- a/docs/basics/accounts-fees.md +++ /dev/null @@ -1,11 +0,0 @@ -# Accounts, Fees and Gas - -## Accounts - -## AnteHandler - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index bca2c0c2774f..af206c06cf6a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 7f8214b34e4c..b0b889f7812d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -29,9 +29,6 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Info](#info) + [Query](#query) - - - ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: @@ -67,12 +64,12 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -89,13 +86,9 @@ Finally, a few more important parameterd: `NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. - -A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. - -## Constructor - +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. ## States @@ -149,8 +142,8 @@ Commit() | | ``` ``` - To perform stateful checks To execute state To answer queries - on received transactions transitions during DeliverTx about last-committed state + To perform stateful checks To execute state To serve queries + on received transactions transitions during DeliverTx on last-committed state +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -246,7 +239,7 @@ The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -258,10 +251,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: @@ -304,7 +297,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. @@ -334,15 +327,30 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then ### InitChain -The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. +The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: + +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. + +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock +The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: + +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. + ### EndBlock +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. + ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. @@ -350,4 +358,19 @@ Finally, `Commit` returns the hash of the commitment of `app.cms` back to the un ### Info +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. + ### Query + +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). + +The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: + +- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). + +## Next + +Learn more about [stores](./store.md). From 0fc3c9a3c130520447f3075ce12e60c9fb9dabb4 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:59:09 +0200 Subject: [PATCH 15/75] remove old files --- docs/core/baseapp_old.md | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/core/baseapp_old.md diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/core/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. From 7b1f376b3dc395885d4166505ebd171b31d3c3c0 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 11 Jul 2019 18:43:04 +0200 Subject: [PATCH 16/75] finish intro --- docs/building-modules/README.md | 78 ++++++++++++++++++++++ docs/building-modules/intro.md | 29 ++++---- docs/building-modules/module-interfaces.md | 8 +++ docs/building-modules/modules-manager.md | 6 ++ docs/core/baseapp.md | 6 +- 5 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 docs/building-modules/README.md create mode 100644 docs/building-modules/modules-manager.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md new file mode 100644 index 000000000000..5b5743671751 --- /dev/null +++ b/docs/building-modules/README.md @@ -0,0 +1,78 @@ +# Auth + +The `x/auth` modules is used for accounts + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) + +# Bank + +The `x/bank` module is for transferring coins between accounts. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) + +# Stake + +The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) + +# Slashing + +The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) + +# Distribution + +The `x/distribution` module is for distributing fees and inflation across bonded +stakeholders. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) + +# Governance + +The `x/gov` module is for bonded stakeholders to make proposals and vote on them. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) + +To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) + +# Crisis + +The `x/crisis` module is for halting the blockchain under certain circumstances. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) + +# Mint + +The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) + +# Params + +The `x/params` module provides a globally available parameter store. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 403eb755a2a2..d3e8440992d5 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,29 +67,28 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: +Modules generally share the same core components: -- Custom [`message` types](./message.md) 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. +- Custom [`message` types](./message.md) 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). - 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). +In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) - +Read more on the [`module interface` and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..377e9ed56f98 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -281,3 +282,10 @@ A few things to note: ## Next Read about the next topic in building modules. +======= +# Module Manager + +## Application Module Interface + +## Module Manager +>>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md new file mode 100644 index 000000000000..c10974af7609 --- /dev/null +++ b/docs/building-modules/modules-manager.md @@ -0,0 +1,6 @@ +# Module Manager + +## Application Module Interface + +## Module Manager + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index b0b889f7812d..d34db4912444 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -34,7 +34,7 @@ This document describes `baseapp`, the abstraction that implements most of the c `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -222,7 +222,7 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the 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). ### Query Routing @@ -321,7 +321,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages From 023c31e1886dbd6226a6330f483801e1fd38ee4e Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 18 Jul 2019 17:20:03 +0200 Subject: [PATCH 17/75] workinnn --- docs/basics/app-anatomy.md | 44 +++---- docs/building-modules/module-interfaces.md | 9 +- docs/building-modules/modules-manager.md | 145 ++++++++++++++++++++- docs/core/baseapp.md | 6 +- 4 files changed, 168 insertions(+), 36 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index af206c06cf6a..2e4613c5e8b6 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -65,6 +65,8 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +To learn more about the `start` command, [click here](../core/node.md#start-command). + ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -73,11 +75,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -88,14 +90,14 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -105,7 +107,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -131,24 +133,20 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +To learn more about the application module interface, [click here](./modules.md#application-module-interface). +======= To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). +>>>>>>> workinnn ### Message Types @@ -171,7 +169,7 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -198,7 +196,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -241,7 +239,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 377e9ed56f98..01b20e6bff15 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -19,6 +18,7 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI +<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands @@ -282,10 +282,3 @@ A few things to note: ## Next Read about the next topic in building modules. -======= -# Module Manager - -## Application Module Interface - -## Module Manager ->>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index c10974af7609..bfe4c9d2d297 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -1,6 +1,147 @@ # Module Manager -## Application Module Interface +## Pre-requisite Reading -## Module Manager +- [Introduction to SDK Modules](./intro.md) +## Synopsis + +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). + +## Application Module Interfaces + +[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: + +- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. +- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). +- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. + +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). + +The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. + +Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which +are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. + +### `AppModuleBasic` + +The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. + +```go +type AppModuleBasic interface { + Name() string + RegisterCodec(*codec.Codec) + + // genesis + DefaultGenesis() json.RawMessage + ValidateGenesis(json.RawMessage) error + + // client functionality + RegisterRESTRoutes(context.CLIContext, *mux.Router) + GetTxCmd(*codec.Codec) *cobra.Command + GetQueryCmd(*codec.Codec) *cobra.Command +} +``` + +Let us go through the methods: + +- `Name()`: Returns the name of the module as a `string`. +- `RegisterCodec(*codec.Codec)`: Registers the `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. +- `RegisterRESTRoutes(context.CLIContext, *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. +- `GetTxCmd(*codec.Codec)`: 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(*codec.Codec)`: Return the root [`query` command](./module-intefaces.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. + +All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). + +### `AppModuleGenesis` + +The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. + +```go +type AppModuleGenesis interface { + AppModuleBasic + InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate + ExportGenesis(sdk.Context) json.RawMessage +} +``` + +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. + +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. + +### `AppModule` + +The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. + +```go +type AppModule interface { + AppModuleGenesis + + // registers + RegisterInvariants(sdk.InvariantRegistry) + + // routes + Route() string + NewHandler() sdk.Handler + QuerierRoute() string + NewQuerierHandler() sdk.Querier + + BeginBlock(sdk.Context, abci.RequestBeginBlock) + EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate +} +``` + +`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. + +Let us go through the methods of `AppModule`: + +- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). +- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. +- `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`. +- `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. + +### Implementing the Application Module Interfaces + +Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). + +Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. + +```go +// example +type AppModule struct { + AppModuleBasic + keeper Keeper +} +``` + +In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. + +If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: + +```go +type AppModuleBasic struct{} +``` + +## Module Managers + +Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. + +### `BasicManager` + +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: + +```go +type BasicManager map[string]AppModuleBasic +``` + + + +### `Manager` diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index d34db4912444..44c46f26f489 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -64,8 +64,8 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. @@ -226,7 +226,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. +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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. 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). From 033af57324ae5139aceb6aff947c487bbf06659c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 11:10:20 -0700 Subject: [PATCH 18/75] initial commit after rebase --- docs/interfaces/cli.md | 145 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 33 +++++++ 2 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 docs/interfaces/query-lifecycle.md diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index fda1ef60b91e..b09d4581cbdf 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,3 +1,144 @@ -# CLI +# Command-Line Interface -> TODO: Rewrite this section to explain how CLI works for a generic SDK app. +## Prerequisites + +* [Anatomy of an SDK App](./app-anatomy.md) + +## Synopsis + +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). + +1. [Application CLI](#Application-cli) +2. [Commands](#commands) +3. [Flags](#flags) +4. [Initialization and Configurations](#initialization-and-configurations) + +## Application CLI + +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. + +### Cobra + +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +### Main Function + +The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: + +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Configurations** are set by reading in configuration files (e.g. the sdk config file). +* **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. +* **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). +* **Create an Executor** and execute the root command. + +The rest of the document will detail what needs to be implemented for each step. + +## Commands + +Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. + +### Root Command + +The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +* [**Transaction**](#transaction-commands) commands. +* [**Query**](#query-commands) commands. + +### Transaction Commands + +Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: + +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** command from the SDK client tools, which broadcasts transactions. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* Any application-specific transaction commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. + +### Query Commands + +Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: + +* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. +* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** command from the SDK rpc client tools, which displays the block data for a given height. +* Any application-specific query commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. + +## Flags + +Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. + +A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. + +### Root Command Flags + +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. + +### Transaction Flags + +To **create** a transaction, the user enters a `tx` command and provides several flags. + +* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much gas, 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. +* `--gas-adjustment` (optional) 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. +* `--gas-prices` 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. +* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. +* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. +* `--indent` (optional) adds an indent to the JSON response. +* `--memo` sends a memo along with the transaction. + +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. + +```bash +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +``` + +To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: + +* `--from` specifies an address; the corresponding private key is used to sign the transaction. +* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. +* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `--account-number` is an identifier for the account. +* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. + +For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. + +```bash +appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +``` + +To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: + +* `--node` specifies which node to broadcast to. +* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. +* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). + +For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. + +```bash +appcli tx broadcast mySignedTx.json --node +``` +### Query Flags + +Queries also have flags. + +* `--node` indicates which full-node to connect to. +* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. +* `--indent` (optional) adds an indent to the JSON response. +* `--height` (optional) can be provided to query the blockchain at a specific height. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. + + +## Initialization and Configurations + +TODO + +## Next + +Read about how to build a CLI for your module [here](./module-interfaces#cli) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md new file mode 100644 index 000000000000..895c83af4abc --- /dev/null +++ b/docs/interfaces/query-lifecycle.md @@ -0,0 +1,33 @@ +# Query Lifecycle + +## Prerequisites + +## Synopsis + +This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. + +1. [Interfaces](#interfaces) +2. [CLIContext](#clicontext) +3. [Tendermint and ABCI](#tendermint-and-abci) +4. [Application Query Handling](#application-query-handling) +5. [Response](#response) + +## Interfaces + +### CLI + +### REST + +## CLIContext + +## Tendermint and ABCI + +## Application Query Handling + +### Baseapp + +## Response + +## Next + +Read about how to build a [Command-Line Interface](./cli.md). From f342f3a99019849945f84c98b22a93da4efd7a48 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 16:19:39 -0700 Subject: [PATCH 19/75] query-lifecycle and started modules-interfaces --- docs/building-modules/module-interfaces.md | 1 - docs/interfaces/cli.md | 16 ++++-- .../{interfaces.md => interfaces-intro.md} | 2 +- docs/interfaces/query-lifecycle.md | 57 +++++++++++++++++-- docs/interfaces/rest.md | 1 + 5 files changed, 64 insertions(+), 13 deletions(-) rename docs/interfaces/{interfaces.md => interfaces-intro.md} (73%) create mode 100644 docs/interfaces/rest.md diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 01b20e6bff15..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,7 +18,6 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b09d4581cbdf..58f9b9422887 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,20 +2,20 @@ ## Prerequisites -* [Anatomy of an SDK App](./app-anatomy.md) +* [Query Lifecycle](./query-lifecycle.md) ## Synopsis This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). -1. [Application CLI](#Application-cli) +1. [Application CLI](#application-cli) 2. [Commands](#commands) 3. [Flags](#flags) 4. [Initialization and Configurations](#initialization-and-configurations) ## Application CLI -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra @@ -135,10 +135,14 @@ Queries also have flags. * `--ledger` (optional) lets the user perform the action using a Ledger Nano S. -## Initialization and Configurations +## Configurations -TODO +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: + +1. Read in the `config.toml` file. This same file is edited through `config` commands. +2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. +3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. ## Next -Read about how to build a CLI for your module [here](./module-interfaces#cli) +Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces.md b/docs/interfaces/interfaces-intro.md similarity index 73% rename from docs/interfaces/interfaces.md rename to docs/interfaces/interfaces-intro.md index bb580a5cf171..43ae0f9a0a6e 100644 --- a/docs/interfaces/interfaces.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO \ No newline at end of file +TODO diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 895c83af4abc..08662b041c25 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -14,20 +14,67 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -### CLI +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. + +## CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: + +``` +appcli query staking delegations +``` + +### CLIContext + +The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: + +* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. +* **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. +* **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. + +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). + +### Parameters and Route Creation + +After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. + +The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). + +A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +### ABCI Query + +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. + +From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). + +## REST + +Another interface through which users can make queries is a REST interface. -### REST -## CLIContext ## Tendermint and ABCI +Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. + +Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). + ## Application Query Handling -### Baseapp +[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 are 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). + +Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. ## Response +The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. + +The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + ## Next -Read about how to build a [Command-Line Interface](./cli.md). +Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md new file mode 100644 index 000000000000..9133e5ce9e2f --- /dev/null +++ b/docs/interfaces/rest.md @@ -0,0 +1 @@ +# REST Interface From f766dc2e5e1c45b5ba3f1d62cd4903830c1cfdfe Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sun, 21 Jul 2019 14:16:18 -0700 Subject: [PATCH 20/75] query-lifecycle first draft done --- docs/interfaces/query-lifecycle.md | 62 ++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 08662b041c25..9635afa59743 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -4,7 +4,7 @@ ## Synopsis -This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. 1. [Interfaces](#interfaces) 2. [CLIContext](#clicontext) @@ -14,19 +14,43 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. -## CLI +For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: +### CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: ``` appcli query staking delegations ``` +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. + +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). + +### REST + +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: + +```bash +http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +``` + +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. + +The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. + +To read about how the router is used, click [here](./rest.md). + +## Request and Command Handling + +The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. + ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. @@ -39,27 +63,19 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. +The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). -A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. - -From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). - -## REST - -Another interface through which users can make queries is a REST interface. - - +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -71,9 +87,15 @@ Since `query` is a custom query type, Baseapp first parses the path to retrieve ## Response -The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. +Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + +### CLI Response + +The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. + +### REST Response -The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From 45fb5f1330cb7adaecf1afd35d6f6a764274e1e1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 23 Jul 2019 09:33:59 -0700 Subject: [PATCH 21/75] module interfaces first draft --- docs/interfaces/query-lifecycle.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 9635afa59743..6c60c92fe3b7 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -32,7 +32,7 @@ This query command is defined by the module developer and added to the list of s ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations @@ -46,7 +46,7 @@ To read about how the router is used, click [here](./rest.md). ## Request and Command Handling -The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,7 +65,7 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. @@ -83,7 +83,7 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [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 are 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). -Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. +Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. ## Response @@ -95,7 +95,7 @@ The application `codec` is used to unmarshal the response to a JSON and the `CLI ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From a77f6070f7568b5cc2883697980ba92cbbf4fc35 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 25 Jul 2019 19:31:35 -0700 Subject: [PATCH 22/75] rest and intro skeletons --- docs/interfaces/cli.md | 12 ++++++------ docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 10 +++++----- docs/interfaces/rest.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 58f9b9422887..94fca6537b06 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,12 +6,12 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -1. [Application CLI](#application-cli) -2. [Commands](#commands) -3. [Flags](#flags) -4. [Initialization and Configurations](#initialization-and-configurations) +- [Application CLI](#application-cli) +- [Commands](#commands) +- [Flags](#flags) +- [Initialization and Configurations](#initialization-and-configurations) ## Application CLI @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 43ae0f9a0a6e..09466179cc60 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO +This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c60c92fe3b7..83fe119d1b7b 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -6,11 +6,11 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. -1. [Interfaces](#interfaces) -2. [CLIContext](#clicontext) -3. [Tendermint and ABCI](#tendermint-and-abci) -4. [Application Query Handling](#application-query-handling) -5. [Response](#response) +- [Interfaces](#interfaces) +- [CLIContext](#clicontext) +- [Tendermint and ABCI](#tendermint-and-abci) +- [Application Query Handling](#application-query-handling) +- [Response](#response) ## Interfaces diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9133e5ce9e2f..ba22e264ab2b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1 +1,30 @@ # REST Interface + +## Prerequisites + +* [Query Lifecycle](./query-lifecycle.md) + +## Synopsis + +This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). + +- [Application REST Interface](#application-rest-interface) +- [REST Server](#rest-server) +- [Router](#router) +- [Registering Routes](#registering-routes) + +## Application REST Interface + +## REST Server + +The SDK REST Server has the following: + +* **Mux Router** +* **CLIContext** +* **Keybase** +* **Logger** +* **Listener** + +## Registering Routes + +For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) From 02843324938f29de64fa89585f74e17ca2a03de0 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 10:34:32 -0700 Subject: [PATCH 23/75] rest and intro done --- docs/interfaces/cli.md | 6 ++-- docs/interfaces/interfaces-intro.md | 44 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 2 ++ docs/interfaces/rest.md | 41 +++++++++++++++++++++------ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 94fca6537b06..75c36f6b3079 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -8,18 +8,18 @@ This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -- [Application CLI](#application-cli) +- [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) - [Initialization and Configurations](#initialization-and-configurations) -## Application CLI +## Application CLI Components One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 09466179cc60..6e6d91d3f6ec 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,45 @@ # Interfaces -This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. +## Prerequisites + +* [Anatomy of an SDK Application](../basics/app-anatomy.md) +* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + + +## Synopsis + +Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. + +- [Types of Application Interfaces](#types-of-application-interfaces) +- [Module vs Application Interfaces](#module-vs-application-interfaces) + + [Module Developer Responsibilities](#module-developer-responsibilities) + + [Application Developer Responsibilities](#application-developer-responsibilities) + + +## Types of Application Interfaces + +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). + + +## Module vs Application Interfaces + +The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. + +### Module Developer Responsibilities + +In regards to interfaces, the module developers' responsibilities include: + +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). +* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. + +Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). + +### Application Developer Responsibilities + +In regards to interfaces, the application developers' responsibilities include: + +* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 83fe119d1b7b..78a7ca4e2035 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,6 +2,8 @@ ## Prerequisites +[Introduction to Interfaces](./interfaces-intro.md) + ## Synopsis This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ba22e264ab2b..9297de98d58b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -3,6 +3,7 @@ ## Prerequisites * [Query Lifecycle](./query-lifecycle.md) +* [Application CLI](./cli.md) ## Synopsis @@ -10,21 +11,45 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) -- [Router](#router) - [Registering Routes](#registering-routes) ## Application REST Interface +Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. + +Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: + +```bash +appcli rest-server --chain-id --trust-node +``` + ## REST Server -The SDK REST Server has the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: + +* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). +* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. +* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager. +* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. +* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. -* **Mux Router** -* **CLIContext** -* **Keybase** -* **Logger** -* **Listener** +Of the five, the only attribute that developers will need to configure is the router. ## Registering Routes -For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) +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 `RegisterRoutes` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. + +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: + +```go +func registerRoutes(rs *lcd.RestServer) { + client.RegisterRoutes(rs.CliCtx, rs.Mux) + app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) +} +``` + +This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` From 54ced8626a496df18d1b74bc9f5e7a8d68b607dd Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 15:38:50 -0700 Subject: [PATCH 24/75] small edits and links --- docs/interfaces/cli.md | 14 +++++----- docs/interfaces/interfaces-intro.md | 13 +++++++--- docs/interfaces/query-lifecycle.md | 40 ++++++++++++++--------------- docs/interfaces/rest.md | 24 ++++++++++++++++- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 75c36f6b3079..5c8d9b9f4811 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,7 +2,7 @@ ## Prerequisites -* [Query Lifecycle](./query-lifecycle.md) +* [Lifecycle of a Query](./query-lifecycle.md) ## Synopsis @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function @@ -49,23 +49,21 @@ The root command (also called `rootCmd`) is what the user first types into the c ### Transaction Commands -Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* Any application-specific transaction commands defined by the application developer. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. * All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. ### Query Commands -Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: * **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* Any application-specific query commands defined by the application developer. * All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. ## Flags diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 6e6d91d3f6ec..9e68ee971027 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -18,18 +18,18 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. ## Module vs Application Interfaces -The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. ### Module Developer Responsibilities In regards to interfaces, the module developers' responsibilities include: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. @@ -41,5 +41,10 @@ In regards to interfaces, the application developers' responsibilities include: * **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. * **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. * **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. + + +## Next + +Read about the [Lifecycle of a Query](./query-lifecycle.md). diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 78a7ca4e2035..b95d6980fae0 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,11 +2,11 @@ ## Prerequisites -[Introduction to Interfaces](./interfaces-intro.md) +* [Introduction to Interfaces](./interfaces-intro.md) ## Synopsis -This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) - [CLIContext](#clicontext) @@ -16,35 +16,33 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: ``` appcli query staking delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. ### REST Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash -http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. - -To read about how the router is used, click [here](./rest.md). +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. ## Request and Command Handling @@ -55,29 +53,29 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. -* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). ### Parameters and Route Creation The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -85,11 +83,11 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [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 are 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). -Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. +Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. ### CLI Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9297de98d58b..ce3b8db10b42 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -10,12 +10,13 @@ This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) +- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) ## Application REST Interface -Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -23,6 +24,27 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. + +### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much gas, 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. +* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. + ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: From e3d819ee096ff8a66eed5b1cc14ad75ac65cf06d Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 30 Jul 2019 20:35:21 -0700 Subject: [PATCH 25/75] comments --- docs/building-modules/module-interfaces.md | 34 +++++++++------------- docs/interfaces/cli.md | 4 +-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..a75b5b0d169a 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -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. +The flags for a module are typically found in the `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 example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ 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). +For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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 for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -183,24 +183,8 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` - 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. -#### BaseReq - -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `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. -* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - ### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. @@ -257,6 +241,16 @@ To read more about how a transaction is generated, visit the transactions docume ### Register Routes +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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 5c8d9b9f4811..974ca5384e33 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -78,7 +78,7 @@ It is common to add a _persistent_ flag for `--chain-id`, the unique identifier ### Transaction Flags -To **create** a transaction, the user enters a `tx` command and provides several flags. +To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: * `--from` indicates which account the transaction originates from. This account is used to sign the transaction. * `--gas` refers to how much gas, 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. @@ -124,7 +124,7 @@ appcli tx broadcast mySignedTx.json --node ``` ### Query Flags -Queries also have flags. +Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: * `--node` indicates which full-node to connect to. * `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. From 4f040c42186643749d6d5a32b57409beb6935253 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 2 Aug 2019 15:31:21 -0700 Subject: [PATCH 26/75] revisions --- docs/building-modules/module-interfaces.md | 17 +-- docs/interfaces/cli.md | 149 +++++++++++++++++++-- docs/interfaces/interfaces-intro.md | 20 +-- docs/interfaces/query-lifecycle.md | 34 ++--- docs/interfaces/rest.md | 12 +- 5 files changed, 173 insertions(+), 59 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index a75b5b0d169a..e4a1ff940713 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in the `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. +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 example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +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). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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 for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. ### Request Types @@ -239,15 +239,6 @@ The request handler can be broken down as follows: To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). -### Register Routes - -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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. - -To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). ### Register Routes diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 974ca5384e33..6287c0d24026 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -11,7 +11,7 @@ This document describes how to create a commmand-line interface for an SDK appli - [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) -- [Initialization and Configurations](#initialization-and-configurations) +- [Configurations](#configurations) ## Application CLI Components @@ -19,19 +19,19 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: -* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The [`codec`](../core/encoding.md) is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](../core/amino.md). * **Configurations** are set by reading in configuration files (e.g. the sdk config file). * **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and execute the root command. -The rest of the document will detail what needs to be implemented for each step. +An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Commands @@ -41,20 +41,74 @@ Every application CLI first constructs a root command, then adds functionality b The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). * **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. * **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. +Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI's `main()` function. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. + + +```go +rootCmd := &cobra.Command{ + Use: "nscli", + Short: "nameservice Client", +} +rootCmd.AddCommand( + rpc.StatusCommand(), + client.ConfigCmd(defaultCLIHome), + queryCmd(cdc, mc), + txCmd(cdc, mc), + client.LineBreak, + lcd.ServeCommand(cdc, registerRoutes), + client.LineBreak, + keys.Commands(), + client.LineBreak, +) +``` + +All of these things are done within the `main()` function. At the end of the `main()` function, it is necessary to create an `executor` and `Execute()` the root command in the `main()` function: + +```go +executor := cli.PrepareMainCmd(rootCmd, "NS", defaultCLIHome) +err := executor.Execute() +``` + ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. * **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. + +Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). + +```go +func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + txCmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + } + + txCmd.AddCommand( + bankcmd.SendTxCmd(cdc), + client.LineBreak, + authcmd.GetSignCommand(cdc), + tx.GetBroadcastCommand(cdc), + client.LineBreak, + ) + + for _, m := range mc { + txCmd.AddCommand(m.GetTxCmd()) + } + + return txCmd +} +``` + ### Query Commands @@ -64,24 +118,55 @@ The root command (also called `rootCmd`) is what the user first types into the c * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. + +Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): + +```go +func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + } + + queryCmd.AddCommand( + rpc.ValidatorCommand(cdc), + rpc.BlockCommand(), + tx.SearchTxCmd(cdc), + tx.QueryTxCmd(cdc), + client.LineBreak, + authcmd.GetAccountCmd(storeAcc, cdc), + ) + + for _, m := range mc { + queryCmd.AddCommand(m.GetQueryCmd()) + } + + return queryCmd +} +``` ## Flags Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. -A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. +A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: + +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +``` ### Transaction Flags To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: -* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much gas, 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. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. * `--gas-adjustment` (optional) 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. * `--gas-prices` 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. * `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. @@ -122,6 +207,7 @@ For example, the following command broadcasts the signed transaction, `mySignedT ```bash appcli tx broadcast mySignedTx.json --node ``` + ### Query Flags Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: @@ -135,12 +221,47 @@ Queries also have flags. These are the basic flags added to every command using ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. +Here is an example of an `initConfig()` function from the nameservice tutorial CLI: + +```go +func initConfig(cmd *cobra.Command) error { + home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) + if err != nil { + return err + } + + cfgFile := path.Join(home, "config", "config.toml") + if _, err := os.Stat(cfgFile); err == nil { + viper.SetConfigFile(cfgFile) + + if err := viper.ReadInConfig(); err != nil { + return err + } + } + if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil { + return err + } + if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { + return err + } + return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) +} +``` + +Here is an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: + +```go +rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { + return initConfig(rootCmd) +} +``` + ## Next Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 9e68ee971027..e457925acaad 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -8,7 +8,7 @@ ## Synopsis -Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. +Typically, SDK applications include some type of interface that users interact with to utilize the application's functionalities. This document introduces user command-line and REST interfaces. - [Types of Application Interfaces](#types-of-application-interfaces) - [Module vs Application Interfaces](#module-vs-application-interfaces) @@ -18,31 +18,31 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. +SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `app/cmd/cli` folder. ## Module vs Application Interfaces -The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is distinct from creating a [module interface](../building-modules/interfaces.md), though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) handled by the module and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within the scope of the module. On the other hand, the application interfaces aggregate module-level interfaces in order to route messages and queries to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. ### Module Developer Responsibilities -In regards to interfaces, the module developers' responsibilities include: +In regards to interfaces, module developers include the following definitions: * **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. -Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). +Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). ### Application Developer Responsibilities -In regards to interfaces, the application developers' responsibilities include: +In regards to interfaces, application developers include: -* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. -* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. -* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. +* **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s). +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. The CLI has a [configurations](./cli.md#configurations) function to set these values. +* **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application. ## Next diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index b95d6980fae0..44026d16bc2d 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -9,7 +9,7 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) -- [CLIContext](#clicontext) +- [Request and Command Handling](#request-and-command-handling) - [Tendermint and ABCI](#tendermint-and-abci) - [Application Query Handling](#application-query-handling) - [Response](#response) @@ -18,11 +18,11 @@ This document describes SDK interfaces in detail through the lifecycle of a quer A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: +The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: ``` appcli query staking delegations @@ -30,20 +30,22 @@ appcli query staking delegations To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. + ## Request and Command Handling The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. @@ -52,7 +54,7 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: -* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. @@ -65,37 +67,37 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[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 are 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). +[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). -Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +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. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ce3b8db10b42..858c4b9420a4 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -16,7 +16,7 @@ This document describes how to create a REST interface for an SDK application. A ## Application REST Interface -Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -32,15 +32,15 @@ HTTP Request types are defined by the module interfaces for every type of transa `BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. -* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. * `Memo` sends a memo along with the transaction. * `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. -* `Gas` refers to how much gas, 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`. +* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. * `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. Additionally, each request may contain arguments such as a specific address pertaining to the request. @@ -59,9 +59,9 @@ Of the five, the only attribute that developers will need to configure is the ro ## 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 `RegisterRoutes` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. +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 `RegisterRoutes()` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. -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: +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: ```go func registerRoutes(rs *lcd.RestServer) { From 0be941032b720329f18f11041103a930925910e6 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 12 Aug 2019 11:35:39 -0400 Subject: [PATCH 27/75] cli.md comments --- docs/interfaces/cli.md | 155 ++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 65 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 6287c0d24026..f1864a2593cb 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -15,11 +15,20 @@ This document describes how to create a commmand-line interface for an SDK appli ## Application CLI Components -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: + +```bash +nscli tx nameservice buy-name --gas auto --gas-prices +``` +The first four strings specify the command: the root command for the entire application `nscli`, the subcommand `tx`, the subcommand `nameservice` to indicate which module to route the command to, and the type of transaction `buy-name`. The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). + +The CLI interacts with a node (running `nsd`) to handle this command. ### Main Function @@ -39,11 +48,53 @@ Every application CLI first constructs a root command, then adds functionality b ### Root Command -The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. - -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). -* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. -* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: +```json +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "node_info": { + "protocol_version": { + "p2p": "4", + "block": "7", + "app": "0" + }, + "id": "53729852020041b956e86685e24394e0bee4373f", + "listen_addr": "10.0.2.15:26656", + "network": "test-chain-Y1OHx6", + "version": "0.24.0-2ce1abc2", + "channels": "4020212223303800", + "moniker": "ubuntu-xenial", + "other": { + "tx_index": "on", + "rpc_addr": "tcp://0.0.0.0:26657" + } + }, + "sync_info": { + "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", + "latest_app_hash": "0000000000000000", + "latest_block_height": "18", + "latest_block_time": "2018-09-17T11:42:19.149920551Z", + "catching_up": false + }, + "validator_info": { + "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" + }, + "voting_power": "10" + } + } +} +``` +* **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +The `config` command can be invoked by typing `appcli config` with optional arguments ` [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration. +* **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +For example, users can type `appcli keys add ` to add a new key and save an encrypted copy to disk, using the flag `--recover` to recover a private key from a seed phrase or the flag `--multisig` to group multiple keys together to create a multisig key. For full details on the `add` key command, see the code [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys/add.go). * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. @@ -77,12 +128,12 @@ err := executor.Execute() ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` needs to add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. -* **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. +* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. +* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* All [module transaction commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). @@ -112,13 +163,13 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { ### Query Commands -[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` needs to add the following commands: -* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. -* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. -* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. -* **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. +* **QueryTx** and/or other transaction [query commands](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go) from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. +* **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. +* All [module query commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): @@ -153,75 +204,49 @@ Flags are used to modify commands. Users can explicitly include them in commands A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -### Root Command Flags - -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go -rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +const FlagFrom = "from" ``` -### Transaction Flags - -To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: - -* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. -* `--gas-adjustment` (optional) 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. -* `--gas-prices` 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. -* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. -* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. -* `--indent` (optional) adds an indent to the JSON response. -* `--memo` sends a memo along with the transaction. +The flag can be added to a command `cmd`, adding a default value and description: -For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. - -```bash -appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. -* `--from` specifies an address; the corresponding private key is used to sign the transaction. -* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. -* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `--account-number` is an identifier for the account. -* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. +### Root Command Flags -For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: -```bash -appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") ``` -To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: +### Transaction and Query Flags -* `--node` specifies which node to broadcast to. -* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. -* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. -For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. ```bash -appcli tx broadcast mySignedTx.json --node +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json ``` -### Query Flags - -Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: +Here are the flags used: -* `--node` indicates which full-node to connect to. -* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. -* `--indent` (optional) adds an indent to the JSON response. -* `--height` (optional) can be provided to query the blockchain at a specific height. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-prices` 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. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: +The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. From 62e1da25b5836aed612272e4973b30bc02b34da1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:53:19 -0400 Subject: [PATCH 28/75] comments --- docs/building-modules/module-interfaces.md | 16 +++++++++ docs/interfaces/query-lifecycle.md | 38 +++++++++++++--------- docs/interfaces/rest.md | 35 ++++++++------------ 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index e4a1ff940713..f1136e63d72c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -183,8 +183,24 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` + 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. +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much [gas](../core/gas.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. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + ### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 44026d16bc2d..7771e4398456 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -16,22 +16,30 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: +The main interface for an application is the command-line interface. Users connect to a full-node and run the CLI directly from their machines - the CLI interacts directly with the full-node. To create `Query` from their terminal, users type the following command: -``` +```bash appcli query staking delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. +Note that the general format is as follows: + +```bash +appcli query [moduleName] [command] --flag +``` + +To provide values such as `--node` (the full-node the CLI connects to), the user must use the `config` command to set them or provide them as flags. This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there. + ### REST Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: @@ -40,15 +48,15 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. ## Request and Command Handling -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,27 +73,27 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[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). +[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). -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. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +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. 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). ## Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 858c4b9420a4..5f187d01ea8c 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,16 +7,20 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) -- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) +- [Request Types](#request-types) ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command in the `main()` function of the CLI interface: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -24,26 +28,7 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. - -### BaseReq -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `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. -* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. ## REST Server @@ -75,3 +60,9 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` + +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. From 8faeacb95e30297fdfe8fa567cf1598d6af4ad33 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:54:43 -0400 Subject: [PATCH 29/75] minor edits --- docs/interfaces/query-lifecycle.md | 2 +- docs/interfaces/rest.md | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 7771e4398456..e6a0fa9f4ff4 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -48,7 +48,7 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 5f187d01ea8c..bf4a010d0fa8 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -12,7 +12,6 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) -- [Request Types](#request-types) ## Application REST Interface @@ -29,7 +28,6 @@ appcli rest-server --chain-id --trust-node ``` - ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: @@ -60,9 +58,3 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` - -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. From 936afccb11128a6514203ee4de119f24834a0511 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 19 Aug 2019 19:31:02 -0700 Subject: [PATCH 30/75] better flow for query lifecycle --- docs/interfaces/query-lifecycle.md | 101 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index e6a0fa9f4ff4..6c69aa454e68 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -8,13 +8,13 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. -- [Interfaces](#interfaces) -- [Request and Command Handling](#request-and-command-handling) -- [Tendermint and ABCI](#tendermint-and-abci) +- [Query Creation](#query-creation) +- [Query Preparation](#query-preparation) +- [RPC](#rpc) - [Application Query Handling](#application-query-handling) - [Response](#response) -## Interfaces +## Query Creation A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. @@ -52,11 +52,11 @@ To provide values such as `--node` (the full-node the CLI connects to) that are The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node. -## Request and Command Handling +## Query Preparation -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing happens within the CLI or REST server and heavily involves a `CLIContext`. ### CLIContext @@ -69,23 +69,69 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). +The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). -### Parameters and Route Creation -The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. -**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +### Arguments and Route Creation -**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -### ABCI Query +#### Parse Arguments -The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -## Tendermint and ABCI +Here is what the code looks like for the CLI command: -With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. +```go +delAddr, err := sdk.AccAddressFromBech32(args[0]) +bz, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr)) +``` + +Here is what the code looks like for the HTTP Request: + +```go +vars := mux.Vars(r) +bech32delegator := vars["delegatorAddr"] +delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) +cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) +if !ok { + return +} +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"`. + +Here is what the code looks like: + +```go +route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorDelegations) +``` + +Now, `Query` exists as a set of encoded arguments and a route to a specific module and its query type. It is ready to be relayed to a full-node. + +#### ABCI Query Call + +The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. + +Here is what the code looks like (for full specification of all `CLIContext` query functionality, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go)): + +```go +node, err := ctx.GetNode() +opts := rpcclient.ABCIQueryOptions{ + Height: ctx.Height, + Prove: !ctx.TrustNode, +} +result, err := node.ABCIQueryWithOptions(path, key, opts) +``` + +## RPC + +With a call to `ABCIQueryWithOptions()`, `Query` is received by a [full-node](../core/encoding.md) which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -103,10 +149,33 @@ Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.R The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +Here is what the code looks like: + +```go +res, _, err := cliCtx.QueryWithData(route, bz) +var resp types.DelegationResponses +if err := cdc.UnmarshalJSON(res, &resp); err != nil { + return err +} +return cliCtx.PrintOutput(resp) +``` + ### REST Response The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +Here is what the code looks like: + +```go +res, height, err := cliCtx.QueryWithData(endpoint, bz) +if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return +} +cliCtx = cliCtx.WithHeight(height) +rest.PostProcessResponse(w, cliCtx, res) +``` + ## Next Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). From 93a9fab1aa0b35b4168c6aeb5e5bc250b6c63052 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 31/75] add transactions into core --- docs/core/transactions.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 docs/core/transactions.md diff --git a/docs/core/transactions.md b/docs/core/transactions.md new file mode 100644 index 000000000000..69a260d3edce --- /dev/null +++ b/docs/core/transactions.md @@ -0,0 +1,84 @@ +# Transactions + +## Prerequisites + +* [Anatomy of an SDK Application](./app-anatomy.md) + +## Synopsis + +This document describes how various components are defined to enable transactions. It also describes how transactions are generated. + +1. [Transactions](#transactions) +2. [Transaction Definition](#transaction-definition) +3. [CLI and REST Interfaces](#cli-and-rest-interfaces) +4. [Messages](#messages) +5. [Transaction Generation](#transaction-generation) +6. [Handlers](#handlers) + + +## Transactions + +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. + +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). + +## Transaction Definition + +Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: + +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. + +A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. + +## CLI and REST Interfaces + +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. + +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#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. + +## Messages + +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. + +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. + +The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. + +* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. +* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. +* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. +* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. +* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. + +While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. + +## Transaction Generation + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). + +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: + +* `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. +* `Keybase` that manages the user's keys and is used to perform signing operations. +* `AccountNumber` from which this transaction originated. +* `Sequence`, the number of transactions that the user has sent out, used to prevent replay attacks. +* `Gas` option chosen by the users for how to calculate how much gas they will need to pay. A common option is "auto" which generates an automatic estimate. +* `GasAdjustment` to adjust the estimate of gas by a scalar value, used to avoid underestimating the amount of gas required. +* `SimulateAndExecute` option to simply simulate the transaction execution without broadcasting. +* `ChainID` representing which blockchain this transaction pertains to. +* `Memo` to send with the transaction. +* `Fees`, the maximum amount the user is willing to pay in fees. Alternative to specifying gas prices. +* `GasPrices`, the amount per unit of gas the user is willing to pay in fees. Alternative to specifying fees. + +The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). + +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. + +## Handlers + +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. From 54ee0673bf7d575b4dac4fca2eb0b1debfaaa03c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 24 Jul 2019 20:16:22 -0700 Subject: [PATCH 32/75] hans comments --- docs/core/transactions.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 69a260d3edce..60c2c9f9ac20 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,26 +18,26 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. -When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). +When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions are defined by module developers. They must implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's agnosticism with applications. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands that will be added to the application `tx` command. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#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. @@ -45,7 +45,7 @@ When users interact with the application's interfaces, they invoke the underlyin **Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. -Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. +Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. @@ -81,4 +81,4 @@ Every message in a transaction must be signed by the addresses specified by `Get ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a [`Handler`](../building-modules/handler.md) to process all of the module's message types. +The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From de0aebf7c9353de77654917dcd28f09121b0ec21 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 18 Jul 2019 10:23:21 -0700 Subject: [PATCH 33/75] add transactions into core --- docs/core/transactions.md | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index 60c2c9f9ac20..a2cd7bb494ee 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,50 +18,46 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L36-L43) are objects that wrap messages and transaction data, created to enable a user to interact with an application. Specifically, they are comprised of metadata held in [contexts](./contexts) and [messages](../modules.md#messages) that trigger state changes within a module and are handled by the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -Transactions messages are defined by module developers. The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: -* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple messages. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to validate transactions. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which are also for transaction validation but only check messages. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. -* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always marshaled (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is [`Amino`](./amino.md). +* **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces -The SDK uses several tools for building [interfaces](./interfaces.md) through which users can create transactions through the command-line or HTTP Requests. Application developers create entrypoints to the application by creating a [command-line interface](./interfaces.md#cli) or [REST interface](./interfaces.md#rest), typically found in the application's `/cmd` folder. These interfaces allow users to interact with the application through command-line or through HTTP requests. +Application developers create entrypoints to the application by creating a [command-line interface](../interfaces/cli.md) 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. -In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../modules/interfaces.md#rest), module developers specify acceptable request types, register REST routes, and create HTTP Request Handlers. +In order for module messages to be utilized in transactions created through these interfaces, module developers must also specify possible user [interactions](../building-modules/interfaces.md), typically in the module's `/client` folder. For the [command-line interface](../building-modules/interfaces.md#cli), module developers create subcommands to add as children to the application top-level transaction command `TxCmd`. For [HTTP requests](../building-modules/interfaces.md#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. ## Messages -**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. +**Messages** are module-specific objects that trigger state transitions within the scope of the module they belong to. Module developers define the messages for their module by implementing the [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L10-L31) interface, and also define a [`Handler`](../building-modules/handler.md) to process them. Messages in a module are typically defined in a `msgs.go` file (though not always), and one handler with multiple functions to handle each of the module's messages is defined in a `handler.go` file. Note: module messages are not to be confused with [ABCI Messages](https://tendermint.com/docs/spec/abci/abci.html#messages) which define interactions between the Tendermint and application layers. While ABCI messages such as CheckTx and DeliverTx contain Transactions, which contain module Messages, they are not to be confused with the module level messages themselves -The [`Msg`](https://github.com/cosmos/cosmos-sdk/blob/97d10210beb55ad4bd6722f7186a80bf7cb140e2/types/tx_msg.go#L10-L31) interface has five required functions. - -* **Route** returns a string that specifies which module this message is a part of and, thus, which module contains the handler used to implement the actions of this message. [Baseapp](./baseapp.md) uses this function to deliver transactions by invoking the correct handler(s). For example, `MsgSend` is defined in and handled by the `bank` module; its `Route` function returns the name of the `bank` module so `Baseapp` understands to use that module's handler. -* **Type** returns a short, human-readable string that describes what the message does. For example, `MsgSend`'s type is `"send"`. -* **ValidateBasic** implements a set of stateless sanity checks for the message and returns an `Error`. For example, the `validateBasic` method for `MsgSend`, the message which sends coins from one account to another, checks that both sender and recipient addresses are valid and the amount is nonnegative. -* **GetSignBytes** returns a `[]byte` representation of the message which is used by the signer to sign it. -* **GetSigners** returns a list of addresses whose corresponding signatures are required for the message to be valid. For example, `MsgSend` requires a signature from the sender of the coins. +To learn more about messages, click [here](../building-modules/messages-and-queries.md#messages). While messages contain the information for state transition logic, a transaction's other metadata and relevant information are stored in the `TxBuilder` and `CLIContext`. ## Transaction Generation -[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction, two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). +Transactions are first created by end-users through an `appcli tx` command through the command-line or a POST request to an HTTPS server. For details about transaction creation, click [here](../basics/tx-lifecycle.md#transaction-creation). + +[`Contexts`](https://godoc.org/context) are immutable objects that contain all the information needed to process a request. In the process of creating a transaction through the `auth` module (though it is not mandatory to create transactions this way), two contexts are created: the [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) and `TxBuilder`. Both are automatically generated and do not need to be defined by application developers, but do require input from the transaction creator (e.g. using flags through the CLI). -The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3a1a635ac03d4bacecf55/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: +The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/txbuilder.go) contains data closely related with the processing of transactions: * `TxEncoder` defined by the developer for this type of transaction. Used to encode messages before being processed by nodes running Tendermint. * `Keybase` that manages the user's keys and is used to perform signing operations. @@ -77,8 +73,8 @@ The [`TxBuilder`](https://github.com/cosmos/cosmos-sdk/blob/73700df8c39d1fe6c3d3 The `CLIContext` is initialized using the application's `codec` and data more closely related to the user interaction with the interface, holding data such as the output to the user and the broadcast mode. Read more about `CLIContext` [here](../interfaces/query-lifecycle.md#clicontext). -Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. +Every message in a transaction must be signed by the addresses specified by `GetSigners`. The signing process must be handled by a module, and the most widely used one is the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module. Signing is automatically performed when the transaction is created, unless the user choses to generate and sign separately. The `TxBuilder` (namely, the `KeyBase`) is used to perform the signing operations, and the `CLIContext` is used to broadcast transactions. ## Handlers -The final components developers must implement to enable transactions are handlers and keeprs. Each module has a Handler to process all of the module's message types. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). +The final components developers must implement to enable transactions are handlers and keepers. Since messages are module types, each module needs a Handler to process all of its message types and enact the state changes within the module's scope. This design puts more responsibility in module developers, allowing application developers to reuse common functionalities without having to implement state transition logic repetitively. To read more about handlers, visit the documentation for building modules [here](../building-modules/handler.md). From 207132cef08703e69bc8a5c5d5b188eaf22b229f Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:28:34 -0700 Subject: [PATCH 34/75] checkout master-docs files --- docs/.vuepress/config.js | 3 +- docs/basics/app-anatomy.md | 94 +++++++--------- docs/building-modules/intro.md | 29 ++--- docs/core/baseapp.md | 165 +++++++++++------------------ docs/core/node.md | 2 +- docs/intro/README.md | 15 +-- docs/intro/sdk-app-architecture.md | 26 ++--- docs/intro/why-app-specific.md | 39 +++---- 8 files changed, 155 insertions(+), 218 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 602d20781420..9ee6a31059c5 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,8 +31,7 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design", - "/intro/ocap" + "/intro/sdk-design" ] }, { diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2e4613c5e8b6..dc58e389342a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,9 +55,9 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](../core/node.md#main-function). +To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -65,8 +65,6 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](../core/node.md#start-command). - ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -75,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +85,16 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: -- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. + - [`InitChainer`](#initchainer): used to initialize the application when it is first started. + - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -107,7 +104,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -119,40 +116,39 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: -To learn more about the application module interface, [click here](./modules.md#application-module-interface). -======= -To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ->>>>>>> workinnn +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. ### Message Types -A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. @@ -161,24 +157,20 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). - ### Handler -The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. -To learn more about handlers, [click here](../building-modules/handler.md). - ### Keeper -[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -192,18 +184,14 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -To learn more about `keepers`, [click here](../building-modules/keeper.md). - ### Querier -[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](../building-modules/querier.md). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). ### Command-Line and REST Interfaces @@ -216,11 +204,9 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). - #### REST -The module's REST interface 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 lets users generate transactions and query the state through REST calls to the application's light client daemon (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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -228,23 +214,19 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). - ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](../interfaces/intro.md). - ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index d3e8440992d5..403eb755a2a2 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,28 +67,29 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules generally share the same core components: +Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./message.md) 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. +- Custom [`message` types](./message.md) 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). - 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 `module` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`module interface` and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 44c46f26f489..6c3d2dd9e506 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,18 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +52,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. - A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. - A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +84,13 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,54 +120,7 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(2) | | | - | | +----------------------+ | | -DeliverTx(tx3) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(3) | | | - +----------------------+ +----------------------+ +----------------------+ -Commit() | | | - v v v - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | - +----------------------+ | | | | - . . . - . . . - . . . - -``` - -``` - To perform stateful checks To execute state To serve queries - on received transactions transitions during DeliverTx on last-committed state - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | - +----------------------+ | | | | -CheckTx(tx1) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(1) | | | | | - +----------------------+ | | | | -CheckTx(tx2) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(2) | | | | | - +----------------------+ | | | | -CheckTx(tx3) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(3) | | | | | - +----------------------+ +----------------------+ | | -DeliverTx(tx1) | | | | - v v | | - +----------------------+ +----------------------+ | | - | | | DeliverState(t)(1) | | | - | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -185,12 +138,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -206,13 +159,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -222,24 +175,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the 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). +The application's `router` is initilalized with all the 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). ### 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. 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). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -251,43 +204,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -295,13 +248,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -311,17 +264,17 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -329,9 +282,9 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. @@ -339,37 +292,37 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. -### Query +### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). ## Next diff --git a/docs/core/node.md b/docs/core/node.md index 36fe12602d0d..85c6152542ad 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## main function +## `main` function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e676fd179b16..9df4e13e443c 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,12 +18,13 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) + diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index a420fe627c33..94007a2742dc 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 0873f87d0e4a..1b160429f6eb 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,35 +40,36 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today From cf60c92b6b1536c1f39b1feeb9c4ac19b8eb678c Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:32:01 -0700 Subject: [PATCH 35/75] deleted some --- docs/basics/app-anatomy.md | 103 +++++++++------- docs/building-modules/modules-manager.md | 147 ----------------------- docs/concepts/encoding.md | 3 - docs/concepts/tx-msgs.md | 5 - 4 files changed, 58 insertions(+), 200 deletions(-) delete mode 100644 docs/building-modules/modules-manager.md delete mode 100644 docs/concepts/encoding.md delete mode 100644 docs/concepts/tx-msgs.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dc58e389342a..15e1c9fc1e22 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,7 +55,7 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node.md#main-function). +To learn more about the `main.go` function, [click here](../core/node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -85,18 +85,19 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - - [`InitChainer`](#initchainer): used to initialize the application when it is first started. - - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -104,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -116,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -124,53 +125,55 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). + +To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. -- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. +To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). + ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. +To learn more about handlers, [click here](../building-modules/handler.md). + ### Keeper -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -184,14 +187,18 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -### Querier +To learn more about `keepers`, [click here](../building-modules/keeper.md). + +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](../building-modules/querier.md). ### Command-Line and REST Interfaces @@ -204,9 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). +To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). + #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface 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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -214,19 +223,23 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). +To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). + ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). +To learn more about interfaces, [click here](../interfaces/intro.md). + ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md deleted file mode 100644 index bfe4c9d2d297..000000000000 --- a/docs/building-modules/modules-manager.md +++ /dev/null @@ -1,147 +0,0 @@ -# Module Manager - -## Pre-requisite Reading - -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). - -## Application Module Interfaces - -[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: - -- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. -- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). -- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. - -The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). - -The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. - -Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which -are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. - -### `AppModuleBasic` - -The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. - -```go -type AppModuleBasic interface { - Name() string - RegisterCodec(*codec.Codec) - - // genesis - DefaultGenesis() json.RawMessage - ValidateGenesis(json.RawMessage) error - - // client functionality - RegisterRESTRoutes(context.CLIContext, *mux.Router) - GetTxCmd(*codec.Codec) *cobra.Command - GetQueryCmd(*codec.Codec) *cobra.Command -} -``` - -Let us go through the methods: - -- `Name()`: Returns the name of the module as a `string`. -- `RegisterCodec(*codec.Codec)`: Registers the `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. -- `RegisterRESTRoutes(context.CLIContext, *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. -- `GetTxCmd(*codec.Codec)`: 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(*codec.Codec)`: Return the root [`query` command](./module-intefaces.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. - -All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). - -### `AppModuleGenesis` - -The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. - -```go -type AppModuleGenesis interface { - AppModuleBasic - InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate - ExportGenesis(sdk.Context) json.RawMessage -} -``` - -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. - -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. - -### `AppModule` - -The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. - -```go -type AppModule interface { - AppModuleGenesis - - // registers - RegisterInvariants(sdk.InvariantRegistry) - - // routes - Route() string - NewHandler() sdk.Handler - QuerierRoute() string - NewQuerierHandler() sdk.Querier - - BeginBlock(sdk.Context, abci.RequestBeginBlock) - EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate -} -``` - -`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. - -Let us go through the methods of `AppModule`: - -- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). -- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. -- `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`. -- `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. - -### Implementing the Application Module Interfaces - -Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). - -Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. - -```go -// example -type AppModule struct { - AppModuleBasic - keeper Keeper -} -``` - -In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. - -If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: - -```go -type AppModuleBasic struct{} -``` - -## Module Managers - -Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. - -### `BasicManager` - -The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: - -```go -type BasicManager map[string]AppModuleBasic -``` - - - -### `Manager` diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md deleted file mode 100644 index 8113f63e9630..000000000000 --- a/docs/concepts/encoding.md +++ /dev/null @@ -1,3 +0,0 @@ -# Amnio Encoding - -TODO \ No newline at end of file diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md deleted file mode 100644 index fde1963e3c2a..000000000000 --- a/docs/concepts/tx-msgs.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transactions and Messages - -## Transactions - -## Messages From 8f9c36c250d2f0893e270943f10d3daaa9ab8d91 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:33:26 -0700 Subject: [PATCH 36/75] remove modules readme --- docs/building-modules/README.md | 78 --------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 docs/building-modules/README.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) From 38c9ab9860350e819d095a62ea2b92a3e4188427 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 19:44:42 -0700 Subject: [PATCH 37/75] cli.md comments --- docs/interfaces/cli.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index f1864a2593cb..ed15192968c5 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: @@ -28,17 +28,17 @@ nscli tx nameservice buy-name --gas auto --gas-prices ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. +Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: +### Creating Flags + +Every flag has a name the user types to include the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go const FlagFrom = "from" ``` -The flag can be added to a command `cmd`, adding a default value and description: +The flag can be added to a command `cmd` right after the command is created, adding a default value and description: ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. Developers are free to create their own custom flags, following this format. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: ```go rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") @@ -228,7 +232,7 @@ rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint ### Transaction and Query Flags -To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. @@ -246,13 +250,13 @@ Here are the flags used: ## Configurations -The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: +The last function to define in `main.go` is `initConfig`, which does exactly what it sounds like - initialize configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. -Here is an example of an `initConfig()` function from the nameservice tutorial CLI: +Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli): ```go func initConfig(cmd *cobra.Command) error { From 19fee8127d6391e7fed91cfe1718ea44d7135fa1 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:05:43 -0700 Subject: [PATCH 38/75] comments --- docs/interfaces/query-lifecycle.md | 43 ++++++++---------------------- docs/interfaces/rest.md | 4 +-- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c69aa454e68..6c8a5b842620 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -60,7 +60,7 @@ The interactions from the users' perspective are a bit different, but the underl ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following: * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. @@ -76,11 +76,11 @@ The `CLIContext`'s primary role is to store data used during interactions with t ### Arguments and Route Creation -At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with. #### Parse Arguments -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: @@ -104,7 +104,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/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"`. Here is what the code looks like: @@ -137,44 +137,23 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation ## Application Query Handling -[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 [querier](../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. 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 queriers [here](../building-modules/querier.md). + +Once a result is received from the querier, `baseapp` begins the process of returning a response to the user. ## Response -Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. +Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. - -Here is what the code looks like: - -```go -res, _, err := cliCtx.QueryWithData(route, bz) -var resp types.DelegationResponses -if err := cdc.UnmarshalJSON(res, &resp); err != nil { - return err -} -return cliCtx.PrintOutput(resp) -``` +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293). ### REST Response -The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. - -Here is what the code looks like: - -```go -res, height, err := cliCtx.QueryWithData(endpoint, bz) -if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return -} -cliCtx = cliCtx.WithHeight(height) -rest.PostProcessResponse(w, cliCtx, res) -``` +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148). ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index bf4a010d0fa8..2b0e3ba2b633 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). +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). - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) @@ -42,7 +42,7 @@ Of the five, the only attribute that developers will need to configure is the ro ## 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 `RegisterRoutes()` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. +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 `RegisterRoutes()` function 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.md/module-interfaces.md#rest) function, application developers simply use the Module Manager to call this function for each module. 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: From c685c3467960045a6d93d6ef8d7c45243cbac929 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:15:45 -0700 Subject: [PATCH 39/75] module-interfaces comments --- docs/building-modules/module-interfaces.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index f1136e63d72c..300bd6b0817c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,11 +18,11 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### 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. Here is an example from the nameservice tutorial: +[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. Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/cli.html#transactions): ```go func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { @@ -74,9 +74,6 @@ This getter function creates the command for the Buy Name transaction. It does t + 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. - -#### GetTxCmd - 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`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. ```go @@ -98,7 +95,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ### Query Commands -[Queries](./messages-and-queries.md) 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 and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://cosmos.network/docs/tutorial/cli.html#queries): ```go func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -137,9 +134,8 @@ This query returns the address that owns a particular name. The getter function + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. -#### GetQueryCmd -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`](#gettxcmd) 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. ### Flags @@ -167,11 +163,13 @@ Since `PostCommands()` includes all of the basic flags required for a transactio ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. + +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. ### Request Types -Request types must be defined for all *transaction* requests. 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. +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](https://cosmos.network/docs/tutorial/rest.html) module: From cef7b4cdabbe0925d1bc97fca7138387289502e5 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 28 Aug 2019 09:06:33 -0700 Subject: [PATCH 40/75] Merge PR #4857: Add Context concept doc --- docs/core/context.md | 132 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/docs/core/context.md b/docs/core/context.md index e69de29bb2d1..64d9eb704276 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -0,0 +1,132 @@ +# Context + +## Synopsis + +This document details the SDK `Context` type. + +- [Context](#context) + - [Synopsis](#synopsis) + - [Prerequisites](#prerequisites) + - [Context Definition](#context-definition) + - [Go Context Package](#go-context-package) + - [Cache Wrapping](#cache-wrapping) + - [Next](#next) + +## Prerequisites + +- [Anatomy of an SDK Application](../basics/app-anatomy.md) +- [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + +## Context Definition + +The SDK `Context` is a custom data structure that contains Go's stdlib [`context`](https://golang.org/pkg/context) +as its base, and has many additional types within its definition that are specific to the Cosmos SDK +and Tendermint. The `Context` is directly passed between methods and functions as an argument. +The `Context` is integral to tx processing in that it allows modules to easily access their respective +[state](./multistore.md) and retrieve transactional context such as the block header and gas meter. + +```go +type Context struct { + ctx context.Context + ms MultiStore + header abci.Header + chainID string + txBytes []byte + logger log.Logger + voteInfo []abci.VoteInfo + gasMeter GasMeter + blockGasMeter GasMeter + checkTx bool + minGasPrice DecCoins + consParams *abci.ConsensusParams + eventManager *EventManager +} +``` + +- **Context:** The base type is a Go [Context](https://golang.org/pkg/context), which is explained further in the [Go Context Package](#go-context-package) section below. +- **Multistore:** Every application's `BaseApp` contains a [`CommitMultiStore`](./multistore.md) which is provided when a `Context` is created. Calling the `KVStore()` and `TransientStore()` methods allows modules to fetch their +respective `KVStore` using their unique `StoreKey`. +- **ABCI Header:** The [header](https://tendermint.com/docs/spec/abci/abci.html#header) is an ABCI type. It carries important information about the state of the blockchain, such as block height and proposer of the current block. +- **Chain ID:** The unique identification number of the blockchain a block pertains to. +- **Transaction Bytes:** The `[]byte` representation of a transaction being processed using the context. Every transaction is processed by various parts of the SDK and consensus engine (e.g. Tendermint) throughout its [lifecycle](../basics/tx-lifecycle.md), some of which to not have any understanding of transaction types. Thus, transactions are marshaled into the generic `[]byte` type using some kind of [encoding format](./encoding.md) such as [Amino](./amino.md). +- **Logger:** A [Logger](https://github.com/tendermint/tendermint/blob/master/libs/log/logger.go) from the Tendermint libraries. Learn more about logs [here](https://tendermint.com/docs/tendermint-core/how-to-read-logs.html#how-to-read-logs). Modules call this method to create their own unique module-specific logger. +- **VoteInfo:** A list of the ABCI type [`VoteInfo`](https://tendermint.com/docs/spec/abci/abci.html#voteinfo), which includes the name of a validator and a boolean indicating whether they have signed the block. +- **Gas Meters:** Specifically, a `gasMeter` for the transaction currently being processed using the context and a `blockGasMeter` for the entire block it belongs to. Users specify how much in fees they wish to pay for the execution of their transaction; these gas meters keep track of how much [gas](../basics/accounts-fees-gas.md) has been used in the transaction or block so far. If the gas meter runs out, execution halts. +- **CheckTx Mode:** A boolean value indicating whether a transaction should be processed in `CheckTx` or `DeliverTx` mode. +- **Min Gas Price:** The minimum [gas](../basics/accounts-fees-gas.md) price a node is willing to take in order to include a transaction in its block. This price is a local value configured by each node individually. +- **Consensus Params:** The ABCI type [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters), which enforce certain limits for the blockchain, such as maximum gas for a block. +- **Event Manager:** The event manager allows any caller with access to a `Context` to emit [`Events`](https://github.com/cosmos/cosmos-sdk/blob/master/types/events.go). Modules may define module specific +`Events` by defining various `Types` and `Attributes` or use the common definitions found in `types/`. Clients +can subscribe or query for these `Events`. These `Events` are collected throughout `DeliverTx`, `BeginBlock`, +and `EndBlock` and are returned to Tendermint for indexing. For example: + +```go +ctx.EventManager().EmitEvent(sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory)), +) +``` + +## Go Context Package + +A basic `Context` is defined in the [Golang Context Package](https://golang.org/pkg/context). A `Context` +is an immutable data structure that carries request-scoped data across APIs and processes. Contexts +are also designed to enable concurrency and to be used in goroutines. + +Contexts are intended to be **immutable**; they should never be edited. Instead, the convention is +to create a child context from its parent using a `With` function. For example: + +``` go +childCtx = parentCtx.WithBlockHeader(header) +``` + +The [Golang Context Package](https://golang.org/pkg/context) documentation instructs developers to +explicitly pass a context `ctx` as the first argument of a process. + +## Cache Wrapping + +The `Context` contains a `MultiStore`, which allows for cache-wrapping functionality: a `CacheMultiStore` +where each `KVStore` is is wrapped with an ephemeral cache. Processes are free to write changes to +the `CacheMultiStore`, then write the changes back to the original state or disregard them if something +goes wrong. The pattern of usage for a Context is as follows: + +1. A process receives a Context `ctx` from its parent process, which provides information needed to + perform the process. +2. The `ctx.ms` is [**cache wrapped**](./multistore.md), i.e. a cached copy of the [multistore](./multistore.md) +is made so that the process can make changes to the state as it executes, without changing the original`ctx.ms` state. +3. The process may read and write from `ctx` as it is executing. It may call a subprocess and pass +`ctx` to it as needed. +4. When a subprocess returns, it checks if the result is a success or failure. If a failure, nothing +needs to be done - the cache wrapped `ctx` is simply discarded. If successful, the changes made to +the cache-wrapped `MultiStore` can be committed to the original `ctx.ms` via `Write()`. + +For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-and-runmsgs) function in +[`baseapp`](./baseapp.md): + +```go +runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) +result = app.runMsgs(runMsgCtx, msgs, mode) +result.GasWanted = gasWanted + +if mode != runTxModeDeliver { + return result +} + +if result.IsOK() { + msCache.Write() +} +``` + +Here is the process: + +1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()` +to cache-wrap the context and multistore. +2. The cache-wrapped context, `runMsgCtx`, is used in `runMsgs` to return a result. +3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the +changes - the result is returned immediately. +4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates +a successful run over all the messages, the cached multistore is written back to the original. + +## Next + +Read about the next core concept. From 6f39d98376c7f720103fe77d20ae4b94a3e5e3e9 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 10 Sep 2019 09:43:37 -0700 Subject: [PATCH 41/75] last comments! --- docs/core/transactions.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index a2cd7bb494ee..c2ea9721e1b5 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -18,20 +18,20 @@ This document describes how various components are defined to enable transaction ## Transactions -[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's Handler. +[**Transactions**](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L36-L43) are objects created by end-users to trigger state changes in the application. Specifically, they are comprised of metadata held in [contexts](./context.md) and [messages](../building-modules/messages-and-queries.md) that trigger state changes within a module through the module's [Handler](../building-modules/handler.md). When users want to interact with an application and make state changes (e.g. sending coins), they create transactions. Each of a transaction's messages must be signed using the private key associated with the appropriate account(s), and then the transaction is broadcasted to the network. A transaction must then be included in a block, validated, and approved by the network through the consensus process. To read more about the lifecycle of a transaction, click [here](../basics/tx-lifecycle.md). ## Transaction Definition -The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface and include an encoder and decoder: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods:: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. -* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. The `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. +* **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum (see the full implementation of `StdTx` [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go)). Note that this function is to be distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. * **TxEncoder:** Nodes running the consensus engine (e.g. Tendermint Core) are responsible for gossiping transactions and ordering them into blocks, but only handle them in the generic `[]byte` form. Transactions are always [marshaled](./encoding.md) (encoded) before they are relayed to nodes, which compacts them to facilitate gossiping and helps maintain the consensus engine's separation from from application logic. The Cosmos SDK allows developers to specify any deterministic encoding format for their applications; the default is Amino. * **TxDecoder:** [ABCI](https://tendermint.com/docs/spec/abci/) calls from the consensus engine to the application, such as `CheckTx` and `DeliverTx`, are used to process transaction data to determine validity and state changes. Since transactions are passed in as `txBytes []byte`, they need to first be unmarshaled (decoded) using `TxDecoder` before any logic is applied. -A transaction is created through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. +A transaction is created by an end-user through one of the possible [interfaces](#interfaces). In the process, two contexts and an array of [messages](#messages) are created, which are then used to [generate](#transaction-generation) the transaction itself. The actual state changes triggered by transactions are enabled by the [handlers](#handlers). The rest of the document will describe each of these components, in this order. ## CLI and REST Interfaces From 02bfe222ac598feb7384ed208d71b0d94056c9da Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 10 Sep 2019 09:44:12 -0700 Subject: [PATCH 42/75] punctuation --- docs/core/transactions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/transactions.md b/docs/core/transactions.md index c2ea9721e1b5..4751be98836e 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -24,7 +24,7 @@ When users want to interact with an application and make state changes (e.g. sen ## Transaction Definition -The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods:: +The transaction objects themselves are SDK types that implement the [`Tx`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L34-L41) interface, which contains the following methods: * **GetMsgs:** unwraps the transaction and returns a list of its message(s) - one transaction may have one or multiple [messages](../building-modules/messages-and-queries.md#messages), which are defined by module developers. * **ValidateBasic:** includes lightweight, [*stateless*](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](../basics/baseapp.md#checktx) and [`DeliverTx`](../basics/baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth) module's `StdTx` `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum (see the full implementation of `StdTx` [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/types/stdtx.go)). Note that this function is to be distinct from the `ValidateBasic` functions for *messages*, which perform basic validity checks on messages only. For example, when [`runTx`](../basics/baseapp.md#runtx-and-runmsgs) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. From 25fdbf274f7a76b861bd0fd43e3647bda3adccd5 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 20 May 2019 14:08:56 +0200 Subject: [PATCH 43/75] consolidate intro --- docs/intro/README.md | 15 +++++------ docs/intro/sdk-app-architecture.md | 26 +++++++++---------- docs/intro/why-app-specific.md | 41 +++++++++++++++--------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/docs/intro/README.md b/docs/intro/README.md index 9df4e13e443c..e753330be21b 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,13 +18,12 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) - diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 94007a2742dc..a420fe627c33 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 1b160429f6eb..ce454383711c 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,40 +40,39 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. - Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) +- Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. From a6bd71e8049c3a2c30085af7dd2cbb129c7c1c2a Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 28 May 2019 17:32:29 +0200 Subject: [PATCH 44/75] querier --- docs/concepts/amino.md | 3 +++ docs/concepts/genesis.md | 3 +++ docs/concepts/handler.md | 1 + docs/concepts/keeper.md | 0 docs/concepts/modules.md | 3 +++ docs/concepts/querier.md | 3 +++ docs/core/node.md | 2 +- docs/intro/README.md | 2 +- 8 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/amino.md create mode 100644 docs/concepts/genesis.md create mode 100644 docs/concepts/handler.md create mode 100644 docs/concepts/keeper.md create mode 100644 docs/concepts/modules.md create mode 100644 docs/concepts/querier.md diff --git a/docs/concepts/amino.md b/docs/concepts/amino.md new file mode 100644 index 000000000000..8113f63e9630 --- /dev/null +++ b/docs/concepts/amino.md @@ -0,0 +1,3 @@ +# Amnio Encoding + +TODO \ No newline at end of file diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md new file mode 100644 index 000000000000..5e3dbd31dcad --- /dev/null +++ b/docs/concepts/genesis.md @@ -0,0 +1,3 @@ +# Genesis File + +TODO \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/concepts/handler.md new file mode 100644 index 000000000000..f8fc820df8de --- /dev/null +++ b/docs/concepts/handler.md @@ -0,0 +1 @@ +# Handlers \ No newline at end of file diff --git a/docs/concepts/keeper.md b/docs/concepts/keeper.md new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md new file mode 100644 index 000000000000..cfd71f817963 --- /dev/null +++ b/docs/concepts/modules.md @@ -0,0 +1,3 @@ +# SDK Modules + +Todo: Intro concept docs on modules \ No newline at end of file diff --git a/docs/concepts/querier.md b/docs/concepts/querier.md new file mode 100644 index 000000000000..3afa9f0cc308 --- /dev/null +++ b/docs/concepts/querier.md @@ -0,0 +1,3 @@ +# Queriers + +TODO \ No newline at end of file diff --git a/docs/core/node.md b/docs/core/node.md index 85c6152542ad..36fe12602d0d 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## `main` function +## main function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e753330be21b..e676fd179b16 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,7 +2,7 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is a framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). From 2101a755f30bcf088e72ac77b6583a641e36500a Mon Sep 17 00:00:00 2001 From: gamarin Date: Wed, 5 Jun 2019 17:10:54 +0200 Subject: [PATCH 45/75] workiiiing --- docs/.vuepress/config.js | 3 +- docs/concepts/app-anatomy.md | 212 +++++++++++++++++++++++++++++++++ docs/intro/why-app-specific.md | 2 +- 3 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 docs/concepts/app-anatomy.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 9ee6a31059c5..d8756aae2385 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,7 +31,8 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design" + "/intro/sdk-design", + "intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md new file mode 100644 index 000000000000..346b35abab80 --- /dev/null +++ b/docs/concepts/app-anatomy.md @@ -0,0 +1,212 @@ +# Anatomy of an SDK Application + +## Pre-requisite reading + +- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) +- [Cosmos SDK design overview](../intro/sdk-design.md) + +## Synopsis + +This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. + +- [Node Client](#node-client) +- [Core Application File](#core-application-file) +- [Modules](#modules) +- [Intefaces](#interfaces) +- [Dependencies and Makefile](#dependencies-and-makefile) + +The core parts listed above will generally translate to the following directory tree: + +``` +./app +├── cmd/ +│ ├── appd +│ └── appcli +├── app.go +├── x/ +│ ├── auth +│ └── bank +├── Gopkg.toml +└── Makefile +``` + +## Node Client (Daemon) + +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. + +``` + ^ +-------------------------------+ ^ + | | | | + | | State+machine = Application | | + | | | | Built with Cosmos SDK + | | ^ + | | + | +----------- | ABCI | ----------+ v + | | + v | ^ + | | | | +Blockchain Node | | Consensus | | + | | | | + | +-------------------------------+ | Tendermint Core + | | | | + | | Networking | | + | | | | + v +-------------------------------+ v +``` +The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). + +To learn more about the `main.go` function, [click here](./node.md#main-function). + +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. + +The `start` command function primarily does three things: + +1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). + +To learn more about the `start` command, [click here](./node.md#start-command). + +## Core Application File + +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. + +### Type Definition of the Application + +The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: + +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. + +You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). + +### Constructor Function + +This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: + +- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instanciate all the `keepers` defined in the application's `type`. +- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. +- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. +- Set the application's [`initChainer`](#initchainer) and mount the stores. +- Return the application. + +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. + +You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). + +### InitChainer + +The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). + +### Register Codec + +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. + +In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. + +You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). + +## Modules + +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. + +To learn more about modules, [click here](./modules.md) + +### Message Types + +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. + +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md) + +### Handler + +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). + +The handler of a module is generally defined in a file called `handler.go` and consists of: + +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. + +Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. + +To learn more about handlers, [click here](./handler.md). + +### Keeper + +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). + +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. + +The `keeper` type definition generally consists of: + +- **Key(s)** to the module's store(s) in the multistore. +- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. + +The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). + +To learn more about `keepers`, [click here](./keeper.md). + +### Querier + +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. + +The `Querier` of a module are defined in a file called `querier.go`, and consists of: + +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](./querier.md). + +### Command-Line and REST Interfaces + +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. + +#### CLI + +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): + +- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). +- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). + +To learn more about modules CLI, [click here](./module-interfaces.md#cli). + +#### REST + +The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. + +See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). + +To learn more about modules REST interface, [click here](./module-interfaces.md#rest). + +## Application Interface + +Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. + +The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: + +- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. + +See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). + +To learn more about interfaces, [click here](./interfaces.md) + +## Dependencies and Makefile + + + +## Next + +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index ce454383711c..0873f87d0e4a 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -74,5 +74,5 @@ The fundamental issue here is that the governance of the application and the gov Clearly, application-specific blockchains are awesome. The Cosmos SDK makes it easier than ever to build them. What are you waiting for? -- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) - Learn more about the [high-level architecture](./sdk-app-architecture) of an SDK application. +- Learn how to build an application-specific blockchain from scratch with the [SDK tutorial](https://cosmos.network/docs/tutorial) From 8ee9c4a4cf437d917825ee3f0d62b58192ebb681 Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 10 Jun 2019 15:13:41 +0200 Subject: [PATCH 46/75] refactor for new module interface --- docs/.vuepress/config.js | 2 +- docs/concepts/app-anatomy.md | 132 +++++++++++++++--------- docs/concepts/{amino.md => encoding.md} | 0 docs/concepts/fees-signature.md | 7 ++ docs/concepts/invariants.md | 5 + docs/concepts/modules.md | 7 +- 6 files changed, 105 insertions(+), 48 deletions(-) rename docs/concepts/{amino.md => encoding.md} (100%) create mode 100644 docs/concepts/fees-signature.md create mode 100644 docs/concepts/invariants.md diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index d8756aae2385..602d20781420 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -32,7 +32,7 @@ module.exports = { "/intro/why-app-specific", "/intro/sdk-app-architecture", "/intro/sdk-design", - "intro/ocap" + "/intro/ocap" ] }, { diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 346b35abab80..1646e0f39e8a 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -28,16 +28,16 @@ The core parts listed above will generally translate to the following directory │ └── bank ├── Gopkg.toml └── Makefile -``` +``` -## Node Client (Daemon) +## Node Client -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. +The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. ``` ^ +-------------------------------+ ^ | | | | - | | State+machine = Application | | + | | State-machine = Application | | | | | | Built with Cosmos SDK | | ^ + | | | +----------- | ABCI | ----------+ v @@ -55,73 +55,111 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: -1- Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2- Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3- Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. +2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. +3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). To learn more about the `start` command, [click here](./node.md#start-command). ## Core Application File -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. +In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. ### Type Definition of the Application The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is a golang embedding of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). -You can see an example of application type definition [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L27-L43). +You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). ### Constructor Function This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: -- Instanciate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instanciate all the `keepers` defined in the application's `type`. -- Initialize the application's [`routes`](./baseapp.md#routing) with the [`handlers`](#handler) of each one of the application's modules. When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's handler using the routes defined here. -- Initialize the application's [query routes](./baseapp.md#query-routing) with the [`queriers`](#querier) of each of the application's modules. When a user query comes in, it is routed to the appropriate module using the query routes defined here. -- Set the application's [`initChainer`](#initchainer) and mount the stores. -- Return the application. +- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Mount the stores. +- Return the application. -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. +Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. -You can see an example of application constructor [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L46-L128). +You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). ### InitChainer -The `initChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application received the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `initChainer` in its constructor via the [`setInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. + +In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. + +You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). + +### BeginBlocker and EndBlocker -You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L137-L155). +The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. + +In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. + +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. + +You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instanciate a codec `cdc` (e.g. [amino](./amino.md)) and calls the `RegisterCodec(*codec.Codec)` method of each module used within the application to register `cdc` to each module. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -In turn, the `RegisterCodec` function of each module register the custom interfaces and type structures of their respective module so that they can be marhsaled and unmarshaled. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). -You can see an example of a `MakeCodec` [here](You can see an example of an `initChainer` [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/app.go#L189-L198).). +You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder. +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) +### Application Module Interface + +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. + +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. + +To learn more about the application module interface, [click here](./modules.md#application-module-interface). + ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Upon receiving the transaction, the application first unmarshalls it. Then, it extracts the message(s) contained in the application. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. If the message is succesfully processed, the state is updated. +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: + +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type `MsgSend` allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). -To learn more about messages, [click here](./tx-msgs.md) +Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. + +To learn more about messages, [click here](./tx-msgs.md). ### Handler @@ -129,8 +167,8 @@ The `handler` refers to the part of the module responsible for processing the me The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is used in `app.go` to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. @@ -140,36 +178,38 @@ To learn more about handlers, [click here](./handler.md). `Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. +`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. The `keeper` type definition generally consists of: -- **Key(s)** to the module's store(s) in the multistore. +- **Key(s)** to the module's store(s) in the multistore. - Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarhsal them when it retrieves them, because stores only accept `[]bytes` as value. +- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. + +Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). To learn more about `keepers`, [click here](./keeper.md). -### Querier +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module are defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is used in `app.go` to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). - - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). To learn more about `queriers`, [click here](./querier.md). ### Command-Line and REST Interfaces -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. +Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. #### CLI -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both build commands on top of the [Cobra Library](https://github.com/spf13/cobra): +Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). @@ -181,7 +221,7 @@ To learn more about modules CLI, [click here](./module-interfaces.md#cli). The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. +- 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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. - One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). @@ -190,23 +230,23 @@ To learn more about modules REST interface, [click here](./module-interfaces.md# ## Application Interface -Interfaces let end-users interract with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. +Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). To learn more about interfaces, [click here](./interfaces.md) -## Dependencies and Makefile +## Dependencies and Makefile ## Next -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). \ No newline at end of file +Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/amino.md b/docs/concepts/encoding.md similarity index 100% rename from docs/concepts/amino.md rename to docs/concepts/encoding.md diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md new file mode 100644 index 000000000000..36982a97b5d8 --- /dev/null +++ b/docs/concepts/fees-signature.md @@ -0,0 +1,7 @@ +# Fees and Signatures + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/invariants.md b/docs/concepts/invariants.md new file mode 100644 index 000000000000..18cd9ad6224f --- /dev/null +++ b/docs/concepts/invariants.md @@ -0,0 +1,5 @@ +# Invariants + +## What is an invariant + +## Invariant Registry \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/concepts/modules.md index cfd71f817963..5c65c4d89f92 100644 --- a/docs/concepts/modules.md +++ b/docs/concepts/modules.md @@ -1,3 +1,8 @@ # SDK Modules -Todo: Intro concept docs on modules \ No newline at end of file +Todo: Intro concept docs on modules + +## Application Module Interface + +## Module Manager + From cefe24d7d008f8069440a45666b78b6980281e77 Mon Sep 17 00:00:00 2001 From: gamarin Date: Tue, 11 Jun 2019 16:09:21 +0200 Subject: [PATCH 47/75] karoly review --- docs/concepts/app-anatomy.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 1646e0f39e8a..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -75,8 +75,8 @@ The first thing defined in `app.go` is the `type` of the application. It is gene - **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. - **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's [`keepers`](#keeper).** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. Most SDK application use [amino](./amino.md) as their `codec`. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). - **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -91,7 +91,10 @@ This function constructs a new application of the type defined above. It is [cal - With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. - With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the application's [`InitChainer`](#initchainer) (used to initialize the application when it is first started), [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker) (called at the beginning and the end of every block) and [`anteHandler`](#baseapp.md#antehandler) (used to handle fees and signature verification). +- Set the remainer of application's parameters: + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. From c3bdae6866f03bfa8e78501dd4515ab61426e1bf Mon Sep 17 00:00:00 2001 From: gamarin Date: Mon, 17 Jun 2019 16:55:53 +0200 Subject: [PATCH 48/75] working on baseapp doc --- docs/concepts/baseapp_old.md | 128 +++++++++++++++++++++++++++++ docs/concepts/store.md | 8 ++ docs/core/baseapp_old.md | 151 +++++++++++++---------------------- 3 files changed, 192 insertions(+), 95 deletions(-) create mode 100644 docs/concepts/baseapp_old.md create mode 100644 docs/concepts/store.md diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/concepts/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. diff --git a/docs/concepts/store.md b/docs/concepts/store.md new file mode 100644 index 000000000000..067eea3b79bd --- /dev/null +++ b/docs/concepts/store.md @@ -0,0 +1,8 @@ +# Store + +## Commit Multi Store + +## Database + +## Main Store + diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index c4f71f33f696..855b03cf1b55 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -1,128 +1,89 @@ # BaseApp -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. +## Pre-requisite Reading -## Routing +- [Anatomy of an SDK application](./app-anatomy.md) +- [Lifecycle of an SDK transaction](./tx-lifecycle.md) -TODO +## Synopsis -## Transaction Life Cycle +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. +- [Introduction](#introduction) +- [Type Definition](#type-definition) +- [States and Modes](#states-and-modes) +- [Routing](#routing) +- [ABCI](#abci) +- [CheckTx](#abci-checktx) +- [DeliverTx](#abci-delivertx) +- [Commit](#abbci-commit) +- [Other ABCI Message](#other-abci-message) + + [Info](#info) + + [SetOption](#setoption) + + [Query](#query) + + [InitChain](#initchain) + + [BeginBlock](#beginblock) + + [EndBlock](#endblock) +- [Gas](#gas) -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. -### CheckTx +## Introduction -During the execution of `CheckTx`, only the AnteHandler is executed. +`baseapp` is an abstraction that implements the core of an SDK application, namely: -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). +- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. -### DeliverTx +The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. +```go +type app struct { + *bam.BaseApp // reference to baseapp + cdc *codec.Codec -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. + // list of application store keys -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. + // list of application keepers + // module manager +} +``` -## Other ABCI Messages +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. +## Type Definition -### Info -TODO complete description +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: -### SetOption -TODO complete description +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. +- -### Query -TODO complete description +## States and Modes -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description +## Routing -### EndBlock -TODO complete description +## ABCI -### Commit -TODO complete description +## ABCI - CheckTx +## ABCI - DeliverTx -## Gas Management +## ABCI - Commit -### Gas: InitChain +## Other ABCI Messages -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. +### Info -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. +### SetOption -### Gas: BeginBlock +### Query -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. +### InitChain -### Gas: DeliverTx +### BeginBlock -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. +### EndBlock -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. +## Gas \ No newline at end of file From 919ced40ce578c3bc86014cdcc962a7b194b181c Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:47:33 +0200 Subject: [PATCH 49/75] baseapp work --- docs/concepts/accounts-fees.md | 11 +++++ docs/concepts/app-anatomy.md | 4 +- docs/concepts/fees-signature.md | 7 --- docs/core/baseapp_old.md | 85 ++++++++++++++++++++++++++++----- 4 files changed, 85 insertions(+), 22 deletions(-) create mode 100644 docs/concepts/accounts-fees.md delete mode 100644 docs/concepts/fees-signature.md diff --git a/docs/concepts/accounts-fees.md b/docs/concepts/accounts-fees.md new file mode 100644 index 000000000000..9f03e0eb033d --- /dev/null +++ b/docs/concepts/accounts-fees.md @@ -0,0 +1,11 @@ +# Accounts, Fees and Signatures + +## Accounts + +## AnteHandler + +## Signatures + +## Fees + +## Gas \ No newline at end of file diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 78d7b1eda675..177a84f19c7e 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/fees-signature.md b/docs/concepts/fees-signature.md deleted file mode 100644 index 36982a97b5d8..000000000000 --- a/docs/concepts/fees-signature.md +++ /dev/null @@ -1,7 +0,0 @@ -# Fees and Signatures - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md index 855b03cf1b55..c239272fcba3 100644 --- a/docs/core/baseapp_old.md +++ b/docs/core/baseapp_old.md @@ -11,7 +11,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Introduction](#introduction) - [Type Definition](#type-definition) -- [States and Modes](#states-and-modes) +- [States](#states) - [Routing](#routing) - [ABCI](#abci) - [CheckTx](#abci-checktx) @@ -33,7 +33,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states and modes](#states-and-modes), as the state-machine can be in different modes depending on the ABCI message it processes. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -54,26 +54,87 @@ Extending the application with `baseapp` gives the former access to all of `base ## Type Definition -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components: +The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#endblock). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* + +First, the important parameters that are initialized during the initialization of the application: + +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. +- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. +- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. + +Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): + +- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). +- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). + +Finally, a few more important parameterd: + +- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. +- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). +- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). + +## States + +`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. + +### Main State + +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. + +``` ++--------+ +--------+ +| | | | +| S +----------------------------> | S' | +| | For each T in B: apply(T) | | ++--------+ +--------+ +``` + +The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. -## States and Modes +### Volatile States + +Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: + +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). ## Routing -## ABCI +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. + +### Message Routing + +Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. + +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). + +### Query Routing + +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. -## ABCI - CheckTx +Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). -## ABCI - DeliverTx +## Main ABCI Messages -## ABCI - Commit + + +### CheckTx + +### DeliverTx + +## RunTx and RunMsg ## Other ABCI Messages +### Commit + ### Info ### SetOption @@ -84,6 +145,4 @@ The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/ba ### BeginBlock -### EndBlock - -## Gas \ No newline at end of file +### EndBlock \ No newline at end of file From a8a06b13642ff3ef8481d1abc347cb127e355ad2 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 27 Jun 2019 11:59:31 +0200 Subject: [PATCH 50/75] reorg --- docs/{concepts => basics}/accounts-fees.md | 0 docs/basics/app-anatomy.md | 63 ++--- docs/building-modules/module-interfaces.md | 280 ++++++++++++++++++++- docs/concepts/app-anatomy.md | 4 +- docs/concepts/baseapp_old.md | 128 ---------- docs/concepts/genesis.md | 3 - docs/concepts/store.md | 8 - docs/core/baseapp_old.md | 148 ----------- docs/{concepts => modules}/handler.md | 0 docs/{concepts => modules}/invariants.md | 0 docs/{concepts => modules}/keeper.md | 0 docs/modules/module-interfaces.md | 5 + docs/{concepts => modules}/modules.md | 0 docs/{concepts => modules}/querier.md | 0 14 files changed, 319 insertions(+), 320 deletions(-) rename docs/{concepts => basics}/accounts-fees.md (100%) delete mode 100644 docs/concepts/baseapp_old.md delete mode 100644 docs/concepts/genesis.md delete mode 100644 docs/concepts/store.md delete mode 100644 docs/core/baseapp_old.md rename docs/{concepts => modules}/handler.md (100%) rename docs/{concepts => modules}/invariants.md (100%) rename docs/{concepts => modules}/keeper.md (100%) create mode 100644 docs/modules/module-interfaces.md rename docs/{concepts => modules}/modules.md (100%) rename docs/{concepts => modules}/querier.md (100%) diff --git a/docs/concepts/accounts-fees.md b/docs/basics/accounts-fees.md similarity index 100% rename from docs/concepts/accounts-fees.md rename to docs/basics/accounts-fees.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 15e1c9fc1e22..bca2c0c2774f 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -57,7 +57,7 @@ The blockchain full-node presents itself as a binary, generally suffixed by `-d` To learn more about the `main.go` function, [click here](../core/node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +87,17 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -105,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -117,13 +117,13 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). @@ -131,15 +131,22 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: + +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. + +`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). @@ -148,9 +155,9 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). @@ -164,8 +171,8 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -189,9 +196,9 @@ The rest of the file defines the `keeper`'s methods, primarily getters and sette To learn more about `keepers`, [click here](../building-modules/keeper.md). -### Querier +### Querier -[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -232,9 +239,9 @@ Interfaces let end-users interact with full-node clients. This means querying da The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 744c439c67f2..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,9 +1,283 @@ # Module Interfaces +## Prerequisites + +* [Building Modules Intro](./intro.md) + +## Synopsis + +This document details how to build CLI and REST interfaces for a module. Examples from various SDK modules will be included. + +- [CLI](#cli) + + [Transaction Commands](#tx-commands) + + [Query Commands](#query-commands) +- [REST](#rest) + + [Request Types](#request-types) + + [Request Handlers](#request-handlers) + + [Register Routes](#register-routes) + ## CLI -### Tx +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. + +### 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. Here is an example from the nameservice tutorial: + +```go +func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "buy-name [name] [amount]", + Short: "bid for existing name or claim new name", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc) + + txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc)) + + if err := cliCtx.EnsureAccountExists(); err != nil { + return err + } + + coins, err := sdk.ParseCoins(args[1]) + if err != nil { + return err + } + + msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress()) + err = msg.ValidateBasic() + if err != nil { + return err + } + + cliCtx.PrintResponse = true + + return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg}, false) + }, + } +} +``` + +This getter function creates the command for the Buy Name transaction. It does the following: + +- **`codec`**. The getter function takes in an application [`codec`](../core/encoding.md) as an argument and returns a reference to the `cobra.command`. Since a module is intended to be used by any application, the `codec` must be provided. +- **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. + + **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. + + **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 [`CLIContext`](./query-lifecycle.md#clicontext) 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 `CLIContext` 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()`. + + A [message](./messages-and-queries.md) is created using all parameters parsed from the command arguments and `CLIContext`. 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. + + +#### GetTxCmd + +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`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. + +```go +func GetTxCmd(cdc *codec.Codec) *cobra.Command { + txCmd := &cobra.Command{ + Use: types.ModuleName, + Short: "Auth transaction subcommands", + DisableFlagParsing: true, + SuggestionsMinimumDistance: 2, + RunE: client.ValidateCmd, + } + txCmd.AddCommand( + GetMultiSignCommand(cdc), + GetSignCommand(cdc), + ) + return txCmd +} +``` + +### Query Commands + +[Queries](./messages-and-queries.md) 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: + +```go +func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "whois [name]", + Short: "Query whois info of name", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + name := args[0] + + res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil) + if err != nil { + fmt.Printf("could not resolve whois - %s \n", string(name)) + return nil + } + + var out nameservice.Whois + cdc.MustUnmarshalJSON(res, &out) + return cliCtx.PrintOutput(out) + }, + } +} + +``` + +This query returns the address that owns a particular name. 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. +- **`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 [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + + If applicable, the `CLIContext` 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 `CLIContext` parameters in this case because the query does not involve any information about the user. + + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). + + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. +- **Flags.** Add any [flags](#flags) to the command. + +#### GetQueryCmd + +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`](#gettxcmd) command. + +### Flags + +[Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. + +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 example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. + +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") +``` + +The input provided for this flag - called `FlagFrom` is a string with the default value of `""` if none is provided. If the user asks for a description of this flag, the description will be printed. + +A flag can be marked as *required* so that an error is automatically thrown if the user does not provide a value: + +```go +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). + +## REST + +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. + +### Request Types + +Request types must be defined for all *transaction* requests. 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](https://cosmos.network/docs/tutorial/rest.html) module: + +```go +type buyNameReq struct { + BaseReq rest.BaseReq `json:"base_req"` + Name string `json:"name"` + Amount string `json:"amount"` + Buyer string `json:"buyer"` +} +``` + +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. + +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much [gas](../core/gas.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. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. + +Here is an example of a request handler for the nameservice module `buyNameReq` request (the same one shown above): + +```go +func buyNameHandler(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + var req buyNameReq + + if !rest.ReadRESTReq(w, r, cdc, &req) { + rest.WriteErrorResponse(w, http.StatusBadRequest, "failed to parse request") + return + } + + baseReq := req.BaseReq.Sanitize() + if !baseReq.ValidateBaic(w) { + return + } + + addr, err := sdk.AccAddressFromBech32(req.Buyer) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + coins, err := sdk.ParseCoins(req.Amount) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + + //create message + msg := nameservice.NewMsgBuyName(req.Name, coins, addr) + err = msg.ValidateBasic() + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error()) + return + } + clientrest.WriteGenerateStdTxResponse(w, cdc, cliCtx, baseReq, []sdk.Msg{msg}) + + } +} +``` + +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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + +The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. + +The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. + +Here is a `registerRoutes` function with one query route example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/rest.html): + +``` go +func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, cdc *codec.Codec, storeName string) { + // ResolveName Query + r.HandleFunc(fmt.Sprintf("/%s/names/{%s}", storeName, restName), resolveNameHandler(cdc, cliCtx, storeName)).Methods("GET") +} +``` + +A few things to note: + +* The router `r` has already been initialized by the application and is passed in here as an argument - this function is able to add on the nameservice module's routes onto any application's router. The application must also provide a [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) that the querier will need to process user requests and the application [`codec`](../core/encoding.md) for encoding and decoding application-specific types. +* `"/%s/names/{%s}", storeName, restName` is the url for the HTTP request. `storeName` is the name of the module, `restName` is a variable provided by the user to specify what kind of query they are making. +* `resolveNameHandler` is the query request handler defined by the module developer. It also takes the application `codec` and `CLIContext` passed in from the user side, as well as the `storeName`. +* `"GET"` is the HTTP Request method. As to be expected, queries are typically GET requests. Transactions are typically POST and PUT requests. + -### Query +## Next -## REST \ No newline at end of file +Read about the next topic in building modules. diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md index 177a84f19c7e..78d7b1eda675 100644 --- a/docs/concepts/app-anatomy.md +++ b/docs/concepts/app-anatomy.md @@ -116,7 +116,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -154,7 +154,7 @@ To learn more about the application module interface, [click here](./modules.md# A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/concepts/baseapp_old.md b/docs/concepts/baseapp_old.md deleted file mode 100644 index c4f71f33f696..000000000000 --- a/docs/concepts/baseapp_old.md +++ /dev/null @@ -1,128 +0,0 @@ -# BaseApp - -The BaseApp defines the foundational implementation for a basic ABCI application -so that your Cosmos-SDK application can communicate with an underlying -Tendermint node. - -The BaseApp is composed of many internal components. Some of the most important -include the `CommitMultiStore` and its internal state. The internal state is -essentially two sub-states, both of which are used for transaction execution -during different phases, `CheckTx` and `DeliverTx` respectively. During block -commitment, only the `DeliverTx` is persisted. - -The BaseApp requires stores to be mounted via capabilities keys - handlers can -only access stores they're given the key to. The `baseApp` ensures all stores are -properly loaded, cached, and committed. One mounted store is considered the -"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the -most recent state. - -The BaseApp distinguishes between two handler types - the `AnteHandler` and the -`MsgHandler`. The former is a global validity check (checking nonces, sigs and -sufficient balances to pay fees, e.g. things that apply to all transaction from -all modules), the later is the full state transition function. - -During `CheckTx` the state transition function is only applied to the `checkTxState` -and should return before any expensive state transitions are run -(this is up to each developer). It also needs to return the estimated gas cost. - -During `DeliverTx` the state transition function is applied to the blockchain -state and the transactions need to be fully executed. - -The BaseApp is responsible for managing the context passed into handlers - -it makes the block header available and provides the right stores for `CheckTx` -and `DeliverTx`. BaseApp is completely agnostic to serialization formats. - -## Routing - -TODO - -## Transaction Life Cycle - -During the execution of a transaction, it may pass through both `CheckTx` and -`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the -proposing validator and is used for the Tendermint mempool for all full nodes. - -Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if -defined), where the AnteHandler is responsible for pre-message validation -checks such as account and signature validation, fee deduction and collection, -and incrementing sequence numbers. - -### CheckTx - -During the execution of `CheckTx`, only the AnteHandler is executed. - -State transitions due to the AnteHandler are persisted between subsequent calls -of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. - -### DeliverTx - -During the execution of `DeliverTx`, the AnteHandler and Handler is executed. - -The transaction execution during `DeliverTx` operates in a similar fashion to -`CheckTx`. However, state transitions that occur during the AnteHandler are -persisted even when the following Handler processing logic fails. - -It is possible that a malicious proposer may include a transaction in a block -that fails the AnteHandler. In this case, all state transitions for the -offending transaction are discarded. - - -## Other ABCI Messages - -Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. - -### Info -TODO complete description - -### SetOption -TODO complete description - -### Query -TODO complete description - -### InitChain -TODO complete description - -During chain initialization InitChain runs the initialization logic directly on -the CommitMultiStore. The deliver and check states are initialized with the -ChainID. - -Note that we do not commit after InitChain, so BeginBlock for block 1 starts -from the deliver state as initialized by InitChain. - -### BeginBlock -TODO complete description - -### EndBlock -TODO complete description - -### Commit -TODO complete description - - -## Gas Management - -### Gas: InitChain - -During InitChain, the block gas meter is initialized with an infinite amount of -gas to run any genesis transactions. - -Additionally, the InitChain request message includes ConsensusParams as -declared in the genesis.json file. - -### Gas: BeginBlock - -The block gas meter is reset during BeginBlock for the deliver state. If no -maximum block gas is set within baseapp then an infinite gas meter is set, -otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. - -### Gas: DeliverTx - -Before the transaction logic is run, the `BlockGasMeter` is first checked to -see if any gas remains. If no gas remains, then `DeliverTx` immediately returns -an error. - -After the transaction has been processed, the used gas (up to the transaction -gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the -meter's limits, then DeliverTx returns an error and the transaction is not -committed. diff --git a/docs/concepts/genesis.md b/docs/concepts/genesis.md deleted file mode 100644 index 5e3dbd31dcad..000000000000 --- a/docs/concepts/genesis.md +++ /dev/null @@ -1,3 +0,0 @@ -# Genesis File - -TODO \ No newline at end of file diff --git a/docs/concepts/store.md b/docs/concepts/store.md deleted file mode 100644 index 067eea3b79bd..000000000000 --- a/docs/concepts/store.md +++ /dev/null @@ -1,8 +0,0 @@ -# Store - -## Commit Multi Store - -## Database - -## Main Store - diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md deleted file mode 100644 index c239272fcba3..000000000000 --- a/docs/core/baseapp_old.md +++ /dev/null @@ -1,148 +0,0 @@ -# BaseApp - -## Pre-requisite Reading - -- [Anatomy of an SDK application](./app-anatomy.md) -- [Lifecycle of an SDK transaction](./tx-lifecycle.md) - -## Synopsis - -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - -- [Introduction](#introduction) -- [Type Definition](#type-definition) -- [States](#states) -- [Routing](#routing) -- [ABCI](#abci) -- [CheckTx](#abci-checktx) -- [DeliverTx](#abci-delivertx) -- [Commit](#abbci-commit) -- [Other ABCI Message](#other-abci-message) - + [Info](#info) - + [SetOption](#setoption) - + [Query](#query) - + [InitChain](#initchain) - + [BeginBlock](#beginblock) - + [EndBlock](#endblock) -- [Gas](#gas) - - -## Introduction - -`baseapp` is an abstraction that implements the core of an SDK application, namely: - -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](./modules.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. - -The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: - -```go -type app struct { - *bam.BaseApp // reference to baseapp - cdc *codec.Codec - - // list of application store keys - - // list of application keepers - - // module manager -} -``` - -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. - -## Type Definition - -The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. - -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* - -First, the important parameters that are initialized during the initialization of the application: - -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. -- A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. -- A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. -- A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. -- A [`anteHandler`](./accounts-fees.md#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. - -Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): - -- `checkState`: This state is updated during [`CheckTx`](#checktx), and reset on [`Commit`](#commit). -- `deliverState`: This state is updated during [`DeliverTx`](#delivertx), and reset on [`Commit`](#commit). - -Finally, a few more important parameterd: - -- `voteInfos`: This parameter carries the list of validators whose precommit is missing, either because they did not vote or because the proposer did not include their vote. This information is carried by the [context](#context) and can be used by the application for various things like punishing absent validators. -- `minGasPrices`: This parameter defines the minimum [gas prices](./accounts-fees.md#gas) accepted by the node. This is a local parameter, meaning each full-node can set a different `minGasPrices`. It is run by the [`anteHandler`](./accounts-fees.md#antehandler) during `CheckTx`, mainly as a spam protection mechanism. The transaction enters the [mempool](https://tendermint.com/docs/tendermint-core/mempool.html#transaction-ordering) only if the gas price of the transaction is superior to one of the minimum gas price in `minGasPrices` (i.e. if `minGasPrices == 1uatom, 1upho`, the `gas-price` of the transaction must be superior to `1uatom` OR `1upho`). -- `appVersion`: Version of the application. It is set in the [application's constructor function](./baseapp.md#constructor-function). - -## States - -`baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. - -### Main State - -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. - -``` -+--------+ +--------+ -| | | | -| S +----------------------------> | S' | -| | For each T in B: apply(T) | | -+--------+ +--------+ -``` - -The main state is held by `baseapp` in a structure called the [`CommitMultiStore`](./store.md#commit-multi-store). This multi-store is used by developers to instantiate all the stores they need for each of their application's modules. - -### Volatile States - -Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: - -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). -- `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - -## Routing - -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `baseapp`, which holds a `router` for messages, and a `query router` for queries. - -### Message Routing - -Messages need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. - -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -### Query Routing - -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. - -Just like the `router`, the `query router` is initilalized with all the query routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](./app-anatomy.md#app-constructor). - -## Main ABCI Messages - - - -### CheckTx - -### DeliverTx - -## RunTx and RunMsg - -## Other ABCI Messages - -### Commit - -### Info - -### SetOption - -### Query - -### InitChain - -### BeginBlock - -### EndBlock \ No newline at end of file diff --git a/docs/concepts/handler.md b/docs/modules/handler.md similarity index 100% rename from docs/concepts/handler.md rename to docs/modules/handler.md diff --git a/docs/concepts/invariants.md b/docs/modules/invariants.md similarity index 100% rename from docs/concepts/invariants.md rename to docs/modules/invariants.md diff --git a/docs/concepts/keeper.md b/docs/modules/keeper.md similarity index 100% rename from docs/concepts/keeper.md rename to docs/modules/keeper.md diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md new file mode 100644 index 000000000000..0cd27c895326 --- /dev/null +++ b/docs/modules/module-interfaces.md @@ -0,0 +1,5 @@ +# Module Interfaces + +## CLI + +## REST \ No newline at end of file diff --git a/docs/concepts/modules.md b/docs/modules/modules.md similarity index 100% rename from docs/concepts/modules.md rename to docs/modules/modules.md diff --git a/docs/concepts/querier.md b/docs/modules/querier.md similarity index 100% rename from docs/concepts/querier.md rename to docs/modules/querier.md From 6bfd1750dadf8ca3b19d77ba1c1f4580e632ae3b Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 12:00:14 +0200 Subject: [PATCH 51/75] almost there --- docs/basics/accounts-fees.md | 2 +- docs/concepts/app-anatomy.md | 255 ------------------------------ docs/concepts/tx-msgs.md | 5 + docs/core/baseapp.md | 194 +++++++++++++---------- docs/modules/handler.md | 1 - docs/modules/invariants.md | 5 - docs/modules/keeper.md | 0 docs/modules/module-interfaces.md | 5 - docs/modules/modules.md | 8 - docs/modules/querier.md | 3 - 10 files changed, 115 insertions(+), 363 deletions(-) delete mode 100644 docs/concepts/app-anatomy.md create mode 100644 docs/concepts/tx-msgs.md delete mode 100644 docs/modules/handler.md delete mode 100644 docs/modules/invariants.md delete mode 100644 docs/modules/keeper.md delete mode 100644 docs/modules/module-interfaces.md delete mode 100644 docs/modules/modules.md delete mode 100644 docs/modules/querier.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md index 9f03e0eb033d..20fe1fb2dac8 100644 --- a/docs/basics/accounts-fees.md +++ b/docs/basics/accounts-fees.md @@ -1,4 +1,4 @@ -# Accounts, Fees and Signatures +# Accounts, Fees and Gas ## Accounts diff --git a/docs/concepts/app-anatomy.md b/docs/concepts/app-anatomy.md deleted file mode 100644 index 78d7b1eda675..000000000000 --- a/docs/concepts/app-anatomy.md +++ /dev/null @@ -1,255 +0,0 @@ -# Anatomy of an SDK Application - -## Pre-requisite reading - -- [High-level overview of the architecture of an SDK application](../intro/sdk-app-architecture.md) -- [Cosmos SDK design overview](../intro/sdk-design.md) - -## Synopsis - -This document describes the core parts of a Cosmos SDK application. The placeholder name for this application will be `app`. - -- [Node Client](#node-client) -- [Core Application File](#core-application-file) -- [Modules](#modules) -- [Intefaces](#interfaces) -- [Dependencies and Makefile](#dependencies-and-makefile) - -The core parts listed above will generally translate to the following directory tree: - -``` -./app -├── cmd/ -│ ├── appd -│ └── appcli -├── app.go -├── x/ -│ ├── auth -│ └── bank -├── Gopkg.toml -└── Makefile -``` - -## Node Client - -The Daemon, or Full-Node Client, is the core process of an SDK-based blockchain. Participants in the network run this process to initialize their state-machine, connect with other full-nodes and update their state-machine as new blocks come in. - -``` - ^ +-------------------------------+ ^ - | | | | - | | State-machine = Application | | - | | | | Built with Cosmos SDK - | | ^ + | | - | +----------- | ABCI | ----------+ v - | | + v | ^ - | | | | -Blockchain Node | | Consensus | | - | | | | - | +-------------------------------+ | Tendermint Core - | | | | - | | Networking | | - | | | | - v +-------------------------------+ v -``` -The blockchain full-node presents itself as a binary, generally suffixed by `-d` (e.g. `appd` for `app` or `gaiad` for the `gaia`) for "daemon". This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefil](#dependencies-and-makefile). - -To learn more about the `main.go` function, [click here](./node.md#main-function). - -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. - -The `start` command function primarily does three things: - -1. Create an instance of the state-machine defined in [`app.go`](#core-application-file) using the `appCreator`. -2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. -3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). - -To learn more about the `start` command, [click here](./node.md#start-command). - -## Core Application File - -In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. - -### Type Definition of the Application - -The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: - -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). - -You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). - -### Constructor Function - -This function constructs a new application of the type defined above. It is [called](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) everytime the full-node is started with the `start` command. Here are the main actions performed by this function: - -- Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the ivnariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. -- Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. - -Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. - -You can see an example of application constructor [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L110-L222). - -### InitChainer - -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. - -In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. - -You can see an example of an `InitChainer` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L235-L239). - -### BeginBlocker and EndBlocker - -The SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two function called `BeginBlocker` and `EndBlocker`. They are called when the application receives respectively the `BeginBlock` and `EndBlock` messages from the Tendermint engine, which happens at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its constructor via the [`SetBeginBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. - -In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. - -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./fees-signature.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. - -You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). - -### Register Codec - -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. - -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](./modules.md#basic-manager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](./modules.md#basic-manager). - -You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) - -## Modules - -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) - -### Application Module Interface - -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. - -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. - -To learn more about the application module interface, [click here](./modules.md#application-module-interface). - -### Message Types - -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: - -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#fees-signature.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. - -For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). - -Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. - -To learn more about messages, [click here](./tx-msgs.md). - -### Handler - -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is realyed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). - -The handler of a module is generally defined in a file called `handler.go` and consists of: - -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. - -Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on wether the message was succesfully processed and. - -To learn more about handlers, [click here](./handler.md). - -### Keeper - -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). - -`Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. - -The `keeper` type definition generally consists of: - -- **Key(s)** to the module's store(s) in the multistore. -- Reference to **other module's `keepers`**. Only needed if the `keeper` needs to access other module's store(s) (either to read or write from them). -- A reference to the application's **codec**. The `keeper` needs it to marshal structs before storing them, or to unmarshal them when it retrieves them, because stores only accept `[]bytes` as value. - -Along with the type definition, the next important component of the `keeper.go` file is the `keeper`'s constructor function, `NewKeeper`. This function instantiates a new `keeper` of the type defined above, with a `codec`, store `keys` and potentially references to other modules' `keeper`s as parameters. The `NewKeeper` function is called from the [application's constructor](#constructor-function). - -The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). - -To learn more about `keepers`, [click here](./keeper.md). - -### Querier - -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. - -The `Querier` of a module are defined in a file called `querier.go`, and consists of: - -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](./baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](./querier.md). - -### Command-Line and REST Interfaces - -Each module defines command-line commands and REST routes to be exposed to end-user via the [application's interfaces](#application-interfaces). This enables end-users to create messages of the types defined in the module, or to query the subset of the state managed by the module. - -#### CLI - -Generally, the commands related to a module are defined in a folder called `client/cli` in the module's folder. The CLI divides commands in two category, transactions and queries, defined in `client/cli/tx.go` and `client/cli/query.go` respectively. Both commands are built on top of the [Cobra Library](https://github.com/spf13/cobra): - -- Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). -- Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). - -To learn more about modules CLI, [click here](./module-interfaces.md#cli). - -#### REST - -The module's REST interface lets users generate transactions and query the state through REST calls to the application's [light-client daemon](./node.md#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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. -- One handler function for each request that can be routed to the given module. These functions implement the core logic necessary to serve the request. - -See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). - -To learn more about modules REST interface, [click here](./module-interfaces.md#rest). - -## Application Interface - -Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. - -The main interface is the [Command-Line Interface](./interfaces.md#cli). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - -- **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. - -See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). - -To learn more about interfaces, [click here](./interfaces.md) - -## Dependencies and Makefile - - - -## Next - -Learn more about the [Lifecycle of a transaction](./tx-lifecycle.md). diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md new file mode 100644 index 000000000000..fde1963e3c2a --- /dev/null +++ b/docs/concepts/tx-msgs.md @@ -0,0 +1,5 @@ +# Transactions and Messages + +## Transactions + +## Messages diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6c3d2dd9e506..7f8214b34e4c 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,21 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + + + + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +55,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. +- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +87,17 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. + +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. + +A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. + +## Constructor -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,7 +127,54 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(2) | | | + | | +----------------------+ | | +DeliverTx(tx3) | | | | | + | | v | | + | | +----------------------+ | | + | | | DeliverState(t)(3) | | | + +----------------------+ +----------------------+ +----------------------+ +Commit() | | | + v v v + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | + +----------------------+ | | | | + . . . + . . . + . . . + +``` + +``` + To perform stateful checks To execute state To answer queries + on received transactions transitions during DeliverTx about last-committed state + +----------------------+ +----------------------+ +----------------------+ + | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | + +----------------------+ | | | | +CheckTx(tx1) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(1) | | | | | + +----------------------+ | | | | +CheckTx(tx2) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(2) | | | | | + +----------------------+ | | | | +CheckTx(tx3) | | | | | + v | | | | + +----------------------+ | | | | + | CheckState(t)(3) | | | | | + +----------------------+ +----------------------+ | | +DeliverTx(tx1) | | | | + v v | | + +----------------------+ +----------------------+ | | + | | | DeliverState(t)(1) | | | + | | +----------------------+ | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -138,12 +192,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -159,13 +213,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -175,24 +229,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the 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). +The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ### 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. 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). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -204,43 +258,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -248,13 +302,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -264,66 +318,36 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages ### InitChain -The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: - -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. -- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. - -Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. +The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. ### BeginBlock -The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: - -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. -- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. -- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. - ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. - ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. - -### Query - -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). - -The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - -- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. -- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). - -## Next - -Learn more about [stores](./store.md). +### Query diff --git a/docs/modules/handler.md b/docs/modules/handler.md deleted file mode 100644 index f8fc820df8de..000000000000 --- a/docs/modules/handler.md +++ /dev/null @@ -1 +0,0 @@ -# Handlers \ No newline at end of file diff --git a/docs/modules/invariants.md b/docs/modules/invariants.md deleted file mode 100644 index 18cd9ad6224f..000000000000 --- a/docs/modules/invariants.md +++ /dev/null @@ -1,5 +0,0 @@ -# Invariants - -## What is an invariant - -## Invariant Registry \ No newline at end of file diff --git a/docs/modules/keeper.md b/docs/modules/keeper.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/modules/module-interfaces.md b/docs/modules/module-interfaces.md deleted file mode 100644 index 0cd27c895326..000000000000 --- a/docs/modules/module-interfaces.md +++ /dev/null @@ -1,5 +0,0 @@ -# Module Interfaces - -## CLI - -## REST \ No newline at end of file diff --git a/docs/modules/modules.md b/docs/modules/modules.md deleted file mode 100644 index 5c65c4d89f92..000000000000 --- a/docs/modules/modules.md +++ /dev/null @@ -1,8 +0,0 @@ -# SDK Modules - -Todo: Intro concept docs on modules - -## Application Module Interface - -## Module Manager - diff --git a/docs/modules/querier.md b/docs/modules/querier.md deleted file mode 100644 index 3afa9f0cc308..000000000000 --- a/docs/modules/querier.md +++ /dev/null @@ -1,3 +0,0 @@ -# Queriers - -TODO \ No newline at end of file From 8c6c26b221250966c99906bcdb1cb7cf24ac5d78 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:53:40 +0200 Subject: [PATCH 52/75] finish first draft --- docs/basics/accounts-fees.md | 11 ------- docs/basics/app-anatomy.md | 4 +-- docs/core/baseapp.md | 63 ++++++++++++++++++++++++------------ 3 files changed, 45 insertions(+), 33 deletions(-) delete mode 100644 docs/basics/accounts-fees.md diff --git a/docs/basics/accounts-fees.md b/docs/basics/accounts-fees.md deleted file mode 100644 index 20fe1fb2dac8..000000000000 --- a/docs/basics/accounts-fees.md +++ /dev/null @@ -1,11 +0,0 @@ -# Accounts, Fees and Gas - -## Accounts - -## AnteHandler - -## Signatures - -## Fees - -## Gas \ No newline at end of file diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index bca2c0c2774f..af206c06cf6a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -117,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -155,7 +155,7 @@ To learn more about the application module interface, [click here](../building-m A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees.md) before extracting the message(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 7f8214b34e4c..b0b889f7812d 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -29,9 +29,6 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Info](#info) + [Query](#query) - - - ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: @@ -67,12 +64,12 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#messages). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#queries). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](./app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](./app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -89,13 +86,9 @@ Finally, a few more important parameterd: `NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setter` functions for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. - -A list of `options` examples can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. - -## Constructor - +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. ## States @@ -149,8 +142,8 @@ Commit() | | ``` ``` - To perform stateful checks To execute state To answer queries - on received transactions transitions during DeliverTx about last-committed state + To perform stateful checks To execute state To serve queries + on received transactions transitions during DeliverTx on last-committed state +----------------------+ +----------------------+ +----------------------+ | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | +----------------------+ | | | | @@ -246,7 +239,7 @@ The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. - The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -258,10 +251,10 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. 4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: @@ -304,7 +297,7 @@ During step 5., each read/write to the store increases the value of `GasConsumed `RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. -The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. @@ -334,15 +327,30 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then ### InitChain -The `InitChain` ABCI message is sent from the underlying Tendermint engine when the chain is first started. +The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: + +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. + +Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. ### BeginBlock +The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: + +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. +- Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. + ### EndBlock +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. + ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock()`, `DeliverTx()` and `EndBlock()` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. @@ -350,4 +358,19 @@ Finally, `Commit` returns the hash of the commitment of `app.cms` back to the un ### Info +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. + ### Query + +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). + +The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: + +- Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). + +## Next + +Learn more about [stores](./store.md). From 96d044186d03b42236ced68a1c942fcf561a2d02 Mon Sep 17 00:00:00 2001 From: gamarin Date: Fri, 5 Jul 2019 19:59:09 +0200 Subject: [PATCH 53/75] remove old files --- docs/core/baseapp_old.md | 128 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 docs/core/baseapp_old.md diff --git a/docs/core/baseapp_old.md b/docs/core/baseapp_old.md new file mode 100644 index 000000000000..c4f71f33f696 --- /dev/null +++ b/docs/core/baseapp_old.md @@ -0,0 +1,128 @@ +# BaseApp + +The BaseApp defines the foundational implementation for a basic ABCI application +so that your Cosmos-SDK application can communicate with an underlying +Tendermint node. + +The BaseApp is composed of many internal components. Some of the most important +include the `CommitMultiStore` and its internal state. The internal state is +essentially two sub-states, both of which are used for transaction execution +during different phases, `CheckTx` and `DeliverTx` respectively. During block +commitment, only the `DeliverTx` is persisted. + +The BaseApp requires stores to be mounted via capabilities keys - handlers can +only access stores they're given the key to. The `baseApp` ensures all stores are +properly loaded, cached, and committed. One mounted store is considered the +"main" (`baseApp.MainStoreKey`) - it holds the latest block header, from which we can find and load the +most recent state. + +The BaseApp distinguishes between two handler types - the `AnteHandler` and the +`MsgHandler`. The former is a global validity check (checking nonces, sigs and +sufficient balances to pay fees, e.g. things that apply to all transaction from +all modules), the later is the full state transition function. + +During `CheckTx` the state transition function is only applied to the `checkTxState` +and should return before any expensive state transitions are run +(this is up to each developer). It also needs to return the estimated gas cost. + +During `DeliverTx` the state transition function is applied to the blockchain +state and the transactions need to be fully executed. + +The BaseApp is responsible for managing the context passed into handlers - +it makes the block header available and provides the right stores for `CheckTx` +and `DeliverTx`. BaseApp is completely agnostic to serialization formats. + +## Routing + +TODO + +## Transaction Life Cycle + +During the execution of a transaction, it may pass through both `CheckTx` and +`DeliverTx` as defined in the ABCI specification. `CheckTx` is executed by the +proposing validator and is used for the Tendermint mempool for all full nodes. + +Both `CheckTx` and `DeliverTx` execute the application's AnteHandler (if +defined), where the AnteHandler is responsible for pre-message validation +checks such as account and signature validation, fee deduction and collection, +and incrementing sequence numbers. + +### CheckTx + +During the execution of `CheckTx`, only the AnteHandler is executed. + +State transitions due to the AnteHandler are persisted between subsequent calls +of `CheckTx` in the check-tx state, unless the AnteHandler fails and aborts. + +### DeliverTx + +During the execution of `DeliverTx`, the AnteHandler and Handler is executed. + +The transaction execution during `DeliverTx` operates in a similar fashion to +`CheckTx`. However, state transitions that occur during the AnteHandler are +persisted even when the following Handler processing logic fails. + +It is possible that a malicious proposer may include a transaction in a block +that fails the AnteHandler. In this case, all state transitions for the +offending transaction are discarded. + + +## Other ABCI Messages + +Besides `CheckTx` and `DeliverTx`, BaseApp handles the following ABCI messages. + +### Info +TODO complete description + +### SetOption +TODO complete description + +### Query +TODO complete description + +### InitChain +TODO complete description + +During chain initialization InitChain runs the initialization logic directly on +the CommitMultiStore. The deliver and check states are initialized with the +ChainID. + +Note that we do not commit after InitChain, so BeginBlock for block 1 starts +from the deliver state as initialized by InitChain. + +### BeginBlock +TODO complete description + +### EndBlock +TODO complete description + +### Commit +TODO complete description + + +## Gas Management + +### Gas: InitChain + +During InitChain, the block gas meter is initialized with an infinite amount of +gas to run any genesis transactions. + +Additionally, the InitChain request message includes ConsensusParams as +declared in the genesis.json file. + +### Gas: BeginBlock + +The block gas meter is reset during BeginBlock for the deliver state. If no +maximum block gas is set within baseapp then an infinite gas meter is set, +otherwise a gas meter with `ConsensusParam.BlockSize.MaxGas` is initialized. + +### Gas: DeliverTx + +Before the transaction logic is run, the `BlockGasMeter` is first checked to +see if any gas remains. If no gas remains, then `DeliverTx` immediately returns +an error. + +After the transaction has been processed, the used gas (up to the transaction +gas limit) is deducted from the BlockGasMeter. If the remaining gas exceeds the +meter's limits, then DeliverTx returns an error and the transaction is not +committed. From 082ef4ccb56f1268a7769e2ce0b1bf7b6194f593 Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 11 Jul 2019 18:43:04 +0200 Subject: [PATCH 54/75] finish intro --- docs/building-modules/README.md | 78 ++++++++++++++++++++++ docs/building-modules/intro.md | 29 ++++---- docs/building-modules/module-interfaces.md | 8 +++ docs/building-modules/modules-manager.md | 6 ++ docs/core/baseapp.md | 6 +- 5 files changed, 109 insertions(+), 18 deletions(-) create mode 100644 docs/building-modules/README.md create mode 100644 docs/building-modules/modules-manager.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md new file mode 100644 index 000000000000..5b5743671751 --- /dev/null +++ b/docs/building-modules/README.md @@ -0,0 +1,78 @@ +# Auth + +The `x/auth` modules is used for accounts + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) + +# Bank + +The `x/bank` module is for transferring coins between accounts. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). + +See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) + +# Stake + +The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) + +# Slashing + +The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) + +# Distribution + +The `x/distribution` module is for distributing fees and inflation across bonded +stakeholders. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) + +# Governance + +The `x/gov` module is for bonded stakeholders to make proposals and vote on them. + +See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) + +See the +[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) + +To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) + +# Crisis + +The `x/crisis` module is for halting the blockchain under certain circumstances. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) + +# Mint + +The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) + +# Params + +The `x/params` module provides a globally available parameter store. + +See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) + +See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index 403eb755a2a2..d3e8440992d5 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,29 +67,28 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: +Modules generally share the same core components: -- Custom [`message` types](./message.md) 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. +- Custom [`message` types](./message.md) 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). - 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). +In addition to these components, modules implement the `module` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) - +Read more on the [`module interface` and the `module manager`](./module-manager.md) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..377e9ed56f98 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,3 +1,4 @@ +<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -281,3 +282,10 @@ A few things to note: ## Next Read about the next topic in building modules. +======= +# Module Manager + +## Application Module Interface + +## Module Manager +>>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md new file mode 100644 index 000000000000..c10974af7609 --- /dev/null +++ b/docs/building-modules/modules-manager.md @@ -0,0 +1,6 @@ +# Module Manager + +## Application Module Interface + +## Module Manager + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index b0b889f7812d..d34db4912444 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -34,7 +34,7 @@ This document describes `baseapp`, the abstraction that implements most of the c `baseapp` is an abstraction that implements the core of an SDK application, namely: - The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). -- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/modules.md). +- A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). - Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: @@ -222,7 +222,7 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the routes using the application's [module manager](./modules.md#module-manager), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +The application's `router` is initilalized with all the 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). ### Query Routing @@ -321,7 +321,7 @@ The `AnteHandler` is theoretically optional, but still a very important componen `RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules.md#handler) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages From 00e88d8cb549122dc258faa4ba0c6dc6af1e879c Mon Sep 17 00:00:00 2001 From: gamarin Date: Thu, 18 Jul 2019 17:20:03 +0200 Subject: [PATCH 55/75] workinnn --- docs/basics/app-anatomy.md | 44 +++---- docs/building-modules/module-interfaces.md | 9 +- docs/building-modules/modules-manager.md | 145 ++++++++++++++++++++- docs/core/baseapp.md | 6 +- 4 files changed, 168 insertions(+), 36 deletions(-) diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index af206c06cf6a..2e4613c5e8b6 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -65,6 +65,8 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). +To learn more about the `start` command, [click here](../core/node.md#start-command). + ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -73,11 +75,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -88,14 +90,14 @@ This function constructs a new application of the type defined above. It is call - Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. - With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -105,7 +107,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -131,24 +133,20 @@ You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/bl ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. - -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: - -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule`'s methods are called from the `module manager`(./modules.md#module-manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +To learn more about the application module interface, [click here](./modules.md#application-module-interface). +======= To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). +>>>>>>> workinnn ### Message Types @@ -171,7 +169,7 @@ The [`handler`](../building-modules/handler.md) refers to the part of the module The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](./baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. @@ -198,7 +196,7 @@ To learn more about `keepers`, [click here](../building-modules/keeper.md). ### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: @@ -241,7 +239,7 @@ The main interface is the [Command-Line Interface](../interfaces/cli.md). The CL - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. - **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 377e9ed56f98..01b20e6bff15 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -1,4 +1,3 @@ -<<<<<<< HEAD # Module Interfaces ## Prerequisites @@ -19,6 +18,7 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI +<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands @@ -282,10 +282,3 @@ A few things to note: ## Next Read about the next topic in building modules. -======= -# Module Manager - -## Application Module Interface - -## Module Manager ->>>>>>> finish intro diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md index c10974af7609..bfe4c9d2d297 100644 --- a/docs/building-modules/modules-manager.md +++ b/docs/building-modules/modules-manager.md @@ -1,6 +1,147 @@ # Module Manager -## Application Module Interface +## Pre-requisite Reading -## Module Manager +- [Introduction to SDK Modules](./intro.md) +## Synopsis + +Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). + +## Application Module Interfaces + +[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: + +- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. +- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). +- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. + +The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). + +The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. + +Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which +are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. + +### `AppModuleBasic` + +The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. + +```go +type AppModuleBasic interface { + Name() string + RegisterCodec(*codec.Codec) + + // genesis + DefaultGenesis() json.RawMessage + ValidateGenesis(json.RawMessage) error + + // client functionality + RegisterRESTRoutes(context.CLIContext, *mux.Router) + GetTxCmd(*codec.Codec) *cobra.Command + GetQueryCmd(*codec.Codec) *cobra.Command +} +``` + +Let us go through the methods: + +- `Name()`: Returns the name of the module as a `string`. +- `RegisterCodec(*codec.Codec)`: Registers the `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. +- `RegisterRESTRoutes(context.CLIContext, *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. +- `GetTxCmd(*codec.Codec)`: 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(*codec.Codec)`: Return the root [`query` command](./module-intefaces.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. + +All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). + +### `AppModuleGenesis` + +The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. + +```go +type AppModuleGenesis interface { + AppModuleBasic + InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate + ExportGenesis(sdk.Context) json.RawMessage +} +``` + +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. + +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. + +### `AppModule` + +The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. + +```go +type AppModule interface { + AppModuleGenesis + + // registers + RegisterInvariants(sdk.InvariantRegistry) + + // routes + Route() string + NewHandler() sdk.Handler + QuerierRoute() string + NewQuerierHandler() sdk.Querier + + BeginBlock(sdk.Context, abci.RequestBeginBlock) + EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate +} +``` + +`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. + +Let us go through the methods of `AppModule`: + +- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). +- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). +- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. +- `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`. +- `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. + +### Implementing the Application Module Interfaces + +Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). + +Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. + +```go +// example +type AppModule struct { + AppModuleBasic + keeper Keeper +} +``` + +In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. + +If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: + +```go +type AppModuleBasic struct{} +``` + +## Module Managers + +Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. + +### `BasicManager` + +The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: + +```go +type BasicManager map[string]AppModuleBasic +``` + + + +### `Manager` diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index d34db4912444..44c46f26f489 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -64,8 +64,8 @@ First, the important parameters that are initialized during the initialization o - A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. -- A [router](#message-routing). The `router` facilitates the routing of [messages](./tx-msgs.md) to the appropriate module for it to be processed. -- A [query router](#query-routing). The `query router` facilitates the routing of [queries](./querier.md) to the appropriate module for it to be processed. +- A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. +- A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. @@ -226,7 +226,7 @@ The application's `router` is initilalized with all the routes using the applica ### Query Routing -Similar to messages, queries need to be routed to the appropriate module's [querier](./querier.md). To do so, `baseapp` holds a [`query router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module [`querier`](./querier.md). Usually, the `path` is the name of the module. +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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. 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). From 996e47d4c6f21c75e2c9a703ea683184e629538b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 11:10:20 -0700 Subject: [PATCH 56/75] initial commit after rebase --- docs/interfaces/cli.md | 145 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 33 +++++++ 2 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 docs/interfaces/query-lifecycle.md diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index fda1ef60b91e..b09d4581cbdf 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -1,3 +1,144 @@ -# CLI +# Command-Line Interface -> TODO: Rewrite this section to explain how CLI works for a generic SDK app. +## Prerequisites + +* [Anatomy of an SDK App](./app-anatomy.md) + +## Synopsis + +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). + +1. [Application CLI](#Application-cli) +2. [Commands](#commands) +3. [Flags](#flags) +4. [Initialization and Configurations](#initialization-and-configurations) + +## Application CLI + +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. + +### Cobra + +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +### Main Function + +The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: + +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Configurations** are set by reading in configuration files (e.g. the sdk config file). +* **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. +* **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). +* **Create an Executor** and execute the root command. + +The rest of the document will detail what needs to be implemented for each step. + +## Commands + +Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively. + +### Root Command + +The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +* [**Transaction**](#transaction-commands) commands. +* [**Query**](#query-commands) commands. + +### Transaction Commands + +Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: + +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** command from the SDK client tools, which broadcasts transactions. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* Any application-specific transaction commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. + +### Query Commands + +Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: + +* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. +* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** command from the SDK rpc client tools, which displays the block data for a given height. +* Any application-specific query commands defined by the application developer. +* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. + +## Flags + +Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. + +A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. + +### Root Command Flags + +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. + +### Transaction Flags + +To **create** a transaction, the user enters a `tx` command and provides several flags. + +* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much gas, 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. +* `--gas-adjustment` (optional) 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. +* `--gas-prices` 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. +* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. +* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. +* `--indent` (optional) adds an indent to the JSON response. +* `--memo` sends a memo along with the transaction. + +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. + +```bash +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +``` + +To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: + +* `--from` specifies an address; the corresponding private key is used to sign the transaction. +* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. +* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. +* `--account-number` is an identifier for the account. +* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. + +For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. + +```bash +appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +``` + +To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: + +* `--node` specifies which node to broadcast to. +* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. +* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). + +For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. + +```bash +appcli tx broadcast mySignedTx.json --node +``` +### Query Flags + +Queries also have flags. + +* `--node` indicates which full-node to connect to. +* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. +* `--indent` (optional) adds an indent to the JSON response. +* `--height` (optional) can be provided to query the blockchain at a specific height. +* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. + + +## Initialization and Configurations + +TODO + +## Next + +Read about how to build a CLI for your module [here](./module-interfaces#cli) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md new file mode 100644 index 000000000000..895c83af4abc --- /dev/null +++ b/docs/interfaces/query-lifecycle.md @@ -0,0 +1,33 @@ +# Query Lifecycle + +## Prerequisites + +## Synopsis + +This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. + +1. [Interfaces](#interfaces) +2. [CLIContext](#clicontext) +3. [Tendermint and ABCI](#tendermint-and-abci) +4. [Application Query Handling](#application-query-handling) +5. [Response](#response) + +## Interfaces + +### CLI + +### REST + +## CLIContext + +## Tendermint and ABCI + +## Application Query Handling + +### Baseapp + +## Response + +## Next + +Read about how to build a [Command-Line Interface](./cli.md). From 5b10675d02b755007105a9d87fbb658599f6cc6b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sat, 20 Jul 2019 16:19:39 -0700 Subject: [PATCH 57/75] query-lifecycle and started modules-interfaces --- docs/building-modules/module-interfaces.md | 1 - docs/interfaces/cli.md | 16 ++++-- .../{interfaces.md => interfaces-intro.md} | 2 +- docs/interfaces/query-lifecycle.md | 57 +++++++++++++++++-- docs/interfaces/rest.md | 1 + 5 files changed, 64 insertions(+), 13 deletions(-) rename docs/interfaces/{interfaces.md => interfaces-intro.md} (73%) create mode 100644 docs/interfaces/rest.md diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 01b20e6bff15..c3ddea3298aa 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,7 +18,6 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -<<<<<<< HEAD One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### Transaction Commands diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index b09d4581cbdf..58f9b9422887 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,20 +2,20 @@ ## Prerequisites -* [Anatomy of an SDK App](./app-anatomy.md) +* [Query Lifecycle](./query-lifecycle.md) ## Synopsis This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). -1. [Application CLI](#Application-cli) +1. [Application CLI](#application-cli) 2. [Commands](#commands) 3. [Flags](#flags) 4. [Initialization and Configurations](#initialization-and-configurations) ## Application CLI -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra @@ -135,10 +135,14 @@ Queries also have flags. * `--ledger` (optional) lets the user perform the action using a Ledger Nano S. -## Initialization and Configurations +## Configurations -TODO +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: + +1. Read in the `config.toml` file. This same file is edited through `config` commands. +2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. +3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. ## Next -Read about how to build a CLI for your module [here](./module-interfaces#cli) +Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces.md b/docs/interfaces/interfaces-intro.md similarity index 73% rename from docs/interfaces/interfaces.md rename to docs/interfaces/interfaces-intro.md index bb580a5cf171..43ae0f9a0a6e 100644 --- a/docs/interfaces/interfaces.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO \ No newline at end of file +TODO diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 895c83af4abc..08662b041c25 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -14,20 +14,67 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -### CLI +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. + +## CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: + +``` +appcli query staking delegations +``` + +### CLIContext + +The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: + +* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. +* **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. +* **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. + +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). + +### Parameters and Route Creation + +After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. + +The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). + +A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. + +### ABCI Query + +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. + +From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). + +## REST + +Another interface through which users can make queries is a REST interface. -### REST -## CLIContext ## Tendermint and ABCI +Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. + +Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). + ## Application Query Handling -### Baseapp +[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 are 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). + +Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. ## Response +The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. + +The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + ## Next -Read about how to build a [Command-Line Interface](./cli.md). +Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md new file mode 100644 index 000000000000..9133e5ce9e2f --- /dev/null +++ b/docs/interfaces/rest.md @@ -0,0 +1 @@ +# REST Interface From b6e4e17dd1aa38e42d0fdba19cdf724651835136 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Sun, 21 Jul 2019 14:16:18 -0700 Subject: [PATCH 58/75] query-lifecycle first draft done --- docs/interfaces/query-lifecycle.md | 62 ++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 08662b041c25..9635afa59743 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -4,7 +4,7 @@ ## Synopsis -This document describes SDK interfaces through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. 1. [Interfaces](#interfaces) 2. [CLIContext](#clicontext) @@ -14,19 +14,43 @@ This document describes SDK interfaces through the lifecycle of a query, from th ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. There are a few ways `query` can be made. +A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. -## CLI +For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. To create this query from the command-line, users would type the following command: +### CLI + +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: ``` appcli query staking delegations ``` +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. + +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). + +### REST + +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: + +```bash +http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +``` + +To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. + +The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. + +To read about how the router is used, click [here](./rest.md). + +## Request and Command Handling + +The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. + ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. @@ -39,27 +63,19 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -After a `CLIContext` is created for the CLI command, the command is parsed to create a query route and arguments. +The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -The command contains arguments; in this case, `query` contains a `delegatorAddress`. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). -A `route` is also created for `query` so that the application will understand how to route it. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is used to make the ABCI call, `ABCIQueryWithOptions`. - -From here, continue reading about how the CLI command is handled by skipping to the [Tendermint and ABCI](#tendermint-and-abci) section, or first read about how to make the same `query` using the [REST Interface](#rest). - -## REST - -Another interface through which users can make queries is a REST interface. - - +The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -71,9 +87,15 @@ Since `query` is a custom query type, Baseapp first parses the path to retrieve ## Response -The ABCI `Query()` function returns an ABCI Response of type `ResponseQuery`. +Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. + +### CLI Response + +The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. + +### REST Response -The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From a708cc2ce26c3ee6e5007dda89299fdc468d0236 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 23 Jul 2019 09:33:59 -0700 Subject: [PATCH 59/75] module interfaces first draft --- docs/interfaces/query-lifecycle.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 9635afa59743..6c60c92fe3b7 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -32,7 +32,7 @@ This query command is defined by the module developer and added to the list of s ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md)(#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations @@ -46,7 +46,7 @@ To read about how the router is used, click [here](./rest.md). ## Request and Command Handling -The user interactions are somewhat similar, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,7 +65,7 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. Since requests can only contain `[]byte`s, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. All of this logic is specified in the module [`querier`](.//building-modules/querier.md). +In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. @@ -83,7 +83,7 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [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 are 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). -Since `query` is a custom query type, Baseapp first parses the path to retrieve the name of the path. retrieves the querier using its `QueryRouter`. +Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. ## Response @@ -95,7 +95,7 @@ The application `codec` is used to unmarshal the response to a JSON and the `CLI ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next From 9affd0f29ed175f0e425061b85c7377f085441bc Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Thu, 25 Jul 2019 19:31:35 -0700 Subject: [PATCH 60/75] rest and intro skeletons --- docs/interfaces/cli.md | 12 ++++++------ docs/interfaces/interfaces-intro.md | 2 +- docs/interfaces/query-lifecycle.md | 10 +++++----- docs/interfaces/rest.md | 29 +++++++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 58f9b9422887..94fca6537b06 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,12 +6,12 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating module interfaces can be found [here](#./module-interfaces.md). +This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -1. [Application CLI](#application-cli) -2. [Commands](#commands) -3. [Flags](#flags) -4. [Initialization and Configurations](#initialization-and-configurations) +- [Application CLI](#application-cli) +- [Commands](#commands) +- [Flags](#flags) +- [Initialization and Configurations](#initialization-and-configurations) ## Application CLI @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 43ae0f9a0a6e..09466179cc60 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,3 @@ # Interfaces -TODO +This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c60c92fe3b7..83fe119d1b7b 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -6,11 +6,11 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. -1. [Interfaces](#interfaces) -2. [CLIContext](#clicontext) -3. [Tendermint and ABCI](#tendermint-and-abci) -4. [Application Query Handling](#application-query-handling) -5. [Response](#response) +- [Interfaces](#interfaces) +- [CLIContext](#clicontext) +- [Tendermint and ABCI](#tendermint-and-abci) +- [Application Query Handling](#application-query-handling) +- [Response](#response) ## Interfaces diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9133e5ce9e2f..ba22e264ab2b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -1 +1,30 @@ # REST Interface + +## Prerequisites + +* [Query Lifecycle](./query-lifecycle.md) + +## Synopsis + +This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). + +- [Application REST Interface](#application-rest-interface) +- [REST Server](#rest-server) +- [Router](#router) +- [Registering Routes](#registering-routes) + +## Application REST Interface + +## REST Server + +The SDK REST Server has the following: + +* **Mux Router** +* **CLIContext** +* **Keybase** +* **Logger** +* **Listener** + +## Registering Routes + +For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) From cf13f009a465860f459702cebb2cba1e174a849f Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 10:34:32 -0700 Subject: [PATCH 61/75] rest and intro done --- docs/interfaces/cli.md | 6 ++-- docs/interfaces/interfaces-intro.md | 44 ++++++++++++++++++++++++++++- docs/interfaces/query-lifecycle.md | 2 ++ docs/interfaces/rest.md | 41 +++++++++++++++++++++------ 4 files changed, 81 insertions(+), 12 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 94fca6537b06..75c36f6b3079 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -8,18 +8,18 @@ This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). -- [Application CLI](#application-cli) +- [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) - [Initialization and Configurations](#initialization-and-configurations) -## Application CLI +## Application CLI Components One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 09466179cc60..6e6d91d3f6ec 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -1,3 +1,45 @@ # Interfaces -This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface. +## Prerequisites + +* [Anatomy of an SDK Application](../basics/app-anatomy.md) +* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) + + +## Synopsis + +Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. + +- [Types of Application Interfaces](#types-of-application-interfaces) +- [Module vs Application Interfaces](#module-vs-application-interfaces) + + [Module Developer Responsibilities](#module-developer-responsibilities) + + [Application Developer Responsibilities](#application-developer-responsibilities) + + +## Types of Application Interfaces + +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). + + +## Module vs Application Interfaces + +The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. + +### Module Developer Responsibilities + +In regards to interfaces, the module developers' responsibilities include: + +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). +* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. + +Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). + +### Application Developer Responsibilities + +In regards to interfaces, the application developers' responsibilities include: + +* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 83fe119d1b7b..78a7ca4e2035 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,6 +2,8 @@ ## Prerequisites +[Introduction to Interfaces](./interfaces-intro.md) + ## Synopsis This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ba22e264ab2b..9297de98d58b 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -3,6 +3,7 @@ ## Prerequisites * [Query Lifecycle](./query-lifecycle.md) +* [Application CLI](./cli.md) ## Synopsis @@ -10,21 +11,45 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) -- [Router](#router) - [Registering Routes](#registering-routes) ## Application REST Interface +Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. + +Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: + +```bash +appcli rest-server --chain-id --trust-node +``` + ## REST Server -The SDK REST Server has the following: +A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: + +* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux). +* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction. +* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager. +* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s. +* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package. -* **Mux Router** -* **CLIContext** -* **Keybase** -* **Logger** -* **Listener** +Of the five, the only attribute that developers will need to configure is the router. ## Registering Routes -For information about how to define REST Routes for modules, click [here](../building-modules.md#rest) +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 `RegisterRoutes` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. + +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: + +```go +func registerRoutes(rs *lcd.RestServer) { + client.RegisterRoutes(rs.CliCtx, rs.Mux) + app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux) +} +``` + +This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` From d64ce4ceacb498ec14e12a8d93525870177ae8e9 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 26 Jul 2019 15:38:50 -0700 Subject: [PATCH 62/75] small edits and links --- docs/interfaces/cli.md | 14 +++++----- docs/interfaces/interfaces-intro.md | 13 +++++++--- docs/interfaces/query-lifecycle.md | 40 ++++++++++++++--------------- docs/interfaces/rest.md | 24 ++++++++++++++++- 4 files changed, 57 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 75c36f6b3079..5c8d9b9f4811 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -2,7 +2,7 @@ ## Prerequisites -* [Query Lifecycle](./query-lifecycle.md) +* [Lifecycle of a Query](./query-lifecycle.md) ## Synopsis @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function @@ -49,23 +49,21 @@ The root command (also called `rootCmd`) is what the user first types into the c ### Transaction Commands -Application [transactions](#./transactions.md) are objects that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* Any application-specific transaction commands defined by the application developer. +* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. * All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. ### Query Commands -Application queries are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: * **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* Any application-specific query commands defined by the application developer. * All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. ## Flags diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 6e6d91d3f6ec..9e68ee971027 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -18,18 +18,18 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). +SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. ## Module vs Application Interfaces -The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. ### Module Developer Responsibilities In regards to interfaces, the module developers' responsibilities include: -* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions. +* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. @@ -41,5 +41,10 @@ In regards to interfaces, the application developers' responsibilities include: * **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. * **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. * **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. + + +## Next + +Read about the [Lifecycle of a Query](./query-lifecycle.md). diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 78a7ca4e2035..b95d6980fae0 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -2,11 +2,11 @@ ## Prerequisites -[Introduction to Interfaces](./interfaces-intro.md) +* [Introduction to Interfaces](./interfaces-intro.md) ## Synopsis -This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`. +This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) - [CLIContext](#clicontext) @@ -16,35 +16,33 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A **query** is a request for information made by users of applications. They can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from the command-line, users would type the following command: +The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: ``` appcli query staking delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must use the `config` command to set them or provide them as flags. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. To see the command itself, click [here](). +This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. ### REST Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash -http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations +GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id`, the ID of the blockchain to make the query to, the user must configure their REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. - -To read about how the router is used, click [here](./rest.md). +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. ## Request and Command Handling @@ -55,29 +53,29 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: * **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. -* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, which translates `[]byte`s into accounts. -* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go). +* **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. +* **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/73e5ef7c13c420f9ee879fdf1b60cf0bdc8f325e/client/context/context.go#L36-L59). +For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). ### Parameters and Route Creation The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -85,11 +83,11 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [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 are 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). -Since `query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. +Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `query` response as an `abci.ResponseQuery`. The `CLIContext` `query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. ### CLI Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 9297de98d58b..ce3b8db10b42 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -10,12 +10,13 @@ This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) +- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) ## Application REST Interface -Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -23,6 +24,27 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. + +### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much gas, 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. +* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. + ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: From cab3c2e7baa6dce30c31b82779e0112f825af3ac Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 30 Jul 2019 20:35:21 -0700 Subject: [PATCH 63/75] comments --- docs/building-modules/module-interfaces.md | 34 +++++++++------------- docs/interfaces/cli.md | 4 +-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index c3ddea3298aa..a75b5b0d169a 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -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. +The flags for a module are typically found in the `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 example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ 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). +For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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 for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. ### Request Types @@ -183,24 +183,8 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` - 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. -#### BaseReq - -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `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. -* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - ### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. @@ -257,6 +241,16 @@ To read more about how a transaction is generated, visit the transactions docume ### Register Routes +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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. + +To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). + +### Register Routes + The application CLI entrypoint will have a `RegisterRoutes` function in its `main.go` file, which calls the `registerRoutes` functions of each module utilized by the application. Module developers need to implement `registerRoutes` for their modules so that applications are able to route messages and queries to their corresponding handlers and queriers. The router used by the SDK is [Gorilla Mux](https://github.com/gorilla/mux). The router is initialized with the Gorilla Mux `NewRouter()` function. Then, the router's `HandleFunc` function can then be used to route urls with the defined request handlers and the HTTP method (e.g. "POST", "GET") as a route matcher. It is recommended to prefix every route with the name of the module to avoid collisions with other modules that have the same query or transaction names. diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 5c8d9b9f4811..974ca5384e33 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -78,7 +78,7 @@ It is common to add a _persistent_ flag for `--chain-id`, the unique identifier ### Transaction Flags -To **create** a transaction, the user enters a `tx` command and provides several flags. +To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: * `--from` indicates which account the transaction originates from. This account is used to sign the transaction. * `--gas` refers to how much gas, 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. @@ -124,7 +124,7 @@ appcli tx broadcast mySignedTx.json --node ``` ### Query Flags -Queries also have flags. +Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: * `--node` indicates which full-node to connect to. * `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. From 2ec8d9458e5bb0d7f193ddd23181e1684c13c077 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Fri, 2 Aug 2019 15:31:21 -0700 Subject: [PATCH 64/75] revisions --- docs/building-modules/module-interfaces.md | 17 +-- docs/interfaces/cli.md | 149 +++++++++++++++++++-- docs/interfaces/interfaces-intro.md | 20 +-- docs/interfaces/query-lifecycle.md | 34 ++--- docs/interfaces/rest.md | 12 +- 5 files changed, 173 insertions(+), 59 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index a75b5b0d169a..e4a1ff940713 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -145,11 +145,11 @@ Finally, the module also needs a `GetQueryCmd`, which aggregates all of the quer [Flags](../interfaces/cli.md#flags) are entered by the user and allow for command customizations. Examples include the [fees](../core/accounts-fees.md) or gas prices users are willing to pay for their transactions. -The flags for a module are typically found in the `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. +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 example, the SDK `./client/flags` package includes a [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. +For example, the SDK `./client/flags` package includes a [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function that adds necessary flags to transaction commands, such as the `from` flag to indicate which address the transaction originates from. Here is an example of how to add a flag using the `from` flag from this function. ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") @@ -163,11 +163,11 @@ A flag can be marked as *required* so that an error is automatically thrown if t cmd.MarkFlagRequired(FlagFrom) ``` -For a full list of what flags are in `PostCommands`, including which are required inputs from users, see the CLI documentation [here](../interfaces/cli.md#transaction-flags). +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). ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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 for all possible requests and handlers for each of them. The REST interface file `rest.go` is typically found in the module's `./x/moduleName/client/rest` folder. +Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. ### Request Types @@ -239,15 +239,6 @@ The request handler can be broken down as follows: To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). -### Register Routes - -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), [`CLIContext`](../interfaces/query-lifecycle.md#clicontext), request [`BaseReq`](../interfaces/rest.md#basereq), and message is passed to `WriteGenerateStdTxResponse` to further process the request. - -To read more about how a transaction is generated, visit the transactions documentation [here](../core/transactions.md#transaction-generation). ### Register Routes diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 974ca5384e33..6287c0d24026 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -11,7 +11,7 @@ This document describes how to create a commmand-line interface for an SDK appli - [Application CLI Components](#application-cli-components) - [Commands](#commands) - [Flags](#flags) -- [Initialization and Configurations](#initialization-and-configurations) +- [Configurations](#configurations) ## Application CLI Components @@ -19,19 +19,19 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. ### Main Function The `main.go` file needs to have a `main()` function that does the following to run the command-line interface: -* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The `codec` is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](./amino.md). +* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The [`codec`](../core/encoding.md) is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](../core/amino.md). * **Configurations** are set by reading in configuration files (e.g. the sdk config file). * **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`. * **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands). * **Create an Executor** and execute the root command. -The rest of the document will detail what needs to be implemented for each step. +An example of the `main()` function for the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go#L26-L67). The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file. ## Commands @@ -41,20 +41,74 @@ Every application CLI first constructs a root command, then adds functionality b The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected `Node`. +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). * **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. * **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. +Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial) CLI's `main()` function. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands. + + +```go +rootCmd := &cobra.Command{ + Use: "nscli", + Short: "nameservice Client", +} +rootCmd.AddCommand( + rpc.StatusCommand(), + client.ConfigCmd(defaultCLIHome), + queryCmd(cdc, mc), + txCmd(cdc, mc), + client.LineBreak, + lcd.ServeCommand(cdc, registerRoutes), + client.LineBreak, + keys.Commands(), + client.LineBreak, +) +``` + +All of these things are done within the `main()` function. At the end of the `main()` function, it is necessary to create an `executor` and `Execute()` the root command in the `main()` function: + +```go +executor := cli.PrepareMainCmd(rootCmd, "NS", defaultCLIHome) +err := executor.Execute() +``` + ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping messages that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module MultiSign command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. * **Broadcast** command from the SDK client tools, which broadcasts transactions. * **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling `GetTxCmd()` on all the modules or using the Module Manager's `AddTxCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. + +Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). + +```go +func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + txCmd := &cobra.Command{ + Use: "tx", + Short: "Transactions subcommands", + } + + txCmd.AddCommand( + bankcmd.SendTxCmd(cdc), + client.LineBreak, + authcmd.GetSignCommand(cdc), + tx.GetBroadcastCommand(cdc), + client.LineBreak, + ) + + for _, m := range mc { + txCmd.AddCommand(m.GetTxCmd()) + } + + return txCmd +} +``` + ### Query Commands @@ -64,24 +118,55 @@ The root command (also called `rootCmd`) is what the user first types into the c * **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. * **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. * **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling `GetQueryCmd()` on all the modules or using the Module Manager's `AddQueryCommands()` function. +* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. + +Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): + +```go +func queryCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { + queryCmd := &cobra.Command{ + Use: "query", + Aliases: []string{"q"}, + Short: "Querying subcommands", + } + + queryCmd.AddCommand( + rpc.ValidatorCommand(cdc), + rpc.BlockCommand(), + tx.SearchTxCmd(cdc), + tx.QueryTxCmd(cdc), + client.LineBreak, + authcmd.GetAccountCmd(storeAcc, cdc), + ) + + for _, m := range mc { + queryCmd.AddCommand(m.GetQueryCmd()) + } + + return queryCmd +} +``` ## Flags Flags are used to modify commands. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. -A _persistent_ flag (as opposed to a _local_ flag) added to a command transcends all of its children. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. +A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: + +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +``` ### Transaction Flags To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: -* `--from` indicates which account the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much gas, 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. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. * `--gas-adjustment` (optional) 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. * `--gas-prices` 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. * `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. @@ -122,6 +207,7 @@ For example, the following command broadcasts the signed transaction, `mySignedT ```bash appcli tx broadcast mySignedTx.json --node ``` + ### Query Flags Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: @@ -135,12 +221,47 @@ Queries also have flags. These are the basic flags added to every command using ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig` should do the following: +The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. +Here is an example of an `initConfig()` function from the nameservice tutorial CLI: + +```go +func initConfig(cmd *cobra.Command) error { + home, err := cmd.PersistentFlags().GetString(cli.HomeFlag) + if err != nil { + return err + } + + cfgFile := path.Join(home, "config", "config.toml") + if _, err := os.Stat(cfgFile); err == nil { + viper.SetConfigFile(cfgFile) + + if err := viper.ReadInConfig(); err != nil { + return err + } + } + if err := viper.BindPFlag(client.FlagChainID, cmd.PersistentFlags().Lookup(client.FlagChainID)); err != nil { + return err + } + if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { + return err + } + return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) +} +``` + +Here is an example of how to add `initConfig` as a `PersistentPreRunE` to the root command: + +```go +rootCmd.PersistentPreRunE = func(_ *cobra.Command, _ []string) error { + return initConfig(rootCmd) +} +``` + ## Next Read about how to build a module CLI [here](./module-interfaces#cli) diff --git a/docs/interfaces/interfaces-intro.md b/docs/interfaces/interfaces-intro.md index 9e68ee971027..e457925acaad 100644 --- a/docs/interfaces/interfaces-intro.md +++ b/docs/interfaces/interfaces-intro.md @@ -8,7 +8,7 @@ ## Synopsis -Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications. +Typically, SDK applications include some type of interface that users interact with to utilize the application's functionalities. This document introduces user command-line and REST interfaces. - [Types of Application Interfaces](#types-of-application-interfaces) - [Module vs Application Interfaces](#module-vs-application-interfaces) @@ -18,31 +18,31 @@ Every application must include some interface users can use to interact with the ## Types of Application Interfaces -SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. +SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `app/cmd/cli` folder. ## Module vs Application Interfaces -The process of creating an application interface is very different from creating a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions. +The process of creating an application interface is distinct from creating a [module interface](../building-modules/interfaces.md), though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) handled by the module and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within the scope of the module. On the other hand, the application interfaces aggregate module-level interfaces in order to route messages and queries to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages. ### Module Developer Responsibilities -In regards to interfaces, the module developers' responsibilities include: +In regards to interfaces, module developers include the following definitions: * **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `tx auth send` transactions. * **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices). * **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request. -Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). +Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md). ### Application Developer Responsibilities -In regards to interfaces, the application developers' responsibilities include: +In regards to interfaces, application developers include: -* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands. -* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node. -* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. -* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application. +* **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s). +* **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node. +* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. The CLI has a [configurations](./cli.md#configurations) function to set these values. +* **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application. ## Next diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index b95d6980fae0..44026d16bc2d 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -9,7 +9,7 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. - [Interfaces](#interfaces) -- [CLIContext](#clicontext) +- [Request and Command Handling](#request-and-command-handling) - [Tendermint and ABCI](#tendermint-and-abci) - [Application Query Handling](#application-query-handling) - [Response](#response) @@ -18,11 +18,11 @@ This document describes SDK interfaces in detail through the lifecycle of a quer A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. -For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. There are a few ways `Query` can be made on the user side. +For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users run the CLI directly from their machines and type commands to create queries. To create this query from their terminal, users would type the following command: +The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: ``` appcli query staking delegations @@ -30,20 +30,22 @@ appcli query staking delegations To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. -This query command is defined by the module developer and added to the list of subcommands by the application developer when creating the CLI. +This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). ### REST -Another interface through which users can make queries is through HTTP Requests to a REST server. The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: +Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: ```bash GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. + ## Request and Command Handling The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. @@ -52,7 +54,7 @@ The interactions from the users' perspective are a bit different, but the underl The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: -* **Codec**: The encoder/decoder used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. +* **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. * **RPC Client**: The [Tendermint RPC Client](https://github.com/tendermint/tendermint/blob/master/rpc/client/interface.go), or node, to which the request will be relayed to. * **Keybase**: A [Key Manager](.//core/accounts-keys.md) used to sign transactions and handle other operations with keys. @@ -65,37 +67,37 @@ For full specification of the `CLIContext` type, click [here](https://github.com The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains a `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type `QueryDelegatorParams`. All query arguments (e.g. the `staking` module also has `QueryValidatorParams` and `QueryBondsParams`) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. Baseapp will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the **node**) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions`. +The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/51b3428f5c0f4fdd2e469147cd90353faa4bd704/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[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 are 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). +[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). -Since `Query` is a custom query type, Baseapp first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +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. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. ## Response -Since `Query()` is an ABCI function, Baseapp returns the `Query` response as an `abci.ResponseQuery`. The `CLIContext` `Query` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof` function before the response is returned. +Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application `codec` is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. ### REST Response -The REST server uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index ce3b8db10b42..858c4b9420a4 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -16,7 +16,7 @@ This document describes how to create a REST interface for an SDK application. A ## Application REST Interface -Building the REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -32,15 +32,15 @@ HTTP Request types are defined by the module interfaces for every type of transa `BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. -* `From` indicates which account the transaction originates from. This account is used to sign the transaction. +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. * `Memo` sends a memo along with the transaction. * `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. -* `Gas` refers to how much gas, 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`. +* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. * `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. Additionally, each request may contain arguments such as a specific address pertaining to the request. @@ -59,9 +59,9 @@ Of the five, the only attribute that developers will need to configure is the ro ## 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 `RegisterRoutes` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. +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 `RegisterRoutes()` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. -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: +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: ```go func registerRoutes(rs *lcd.RestServer) { From f53347f03e204a21443bd2a611d45960e977bc2d Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 12 Aug 2019 11:35:39 -0400 Subject: [PATCH 65/75] cli.md comments --- docs/interfaces/cli.md | 155 ++++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 65 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index 6287c0d24026..f1864a2593cb 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -15,11 +15,20 @@ This document describes how to create a commmand-line interface for an SDK appli ## Application CLI Components -One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. +One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial) ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules/modules-manager.md) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. + +Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: + +```bash +nscli tx nameservice buy-name --gas auto --gas-prices +``` +The first four strings specify the command: the root command for the entire application `nscli`, the subcommand `tx`, the subcommand `nameservice` to indicate which module to route the command to, and the type of transaction `buy-name`. The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user). + +The CLI interacts with a node (running `nsd`) to handle this command. ### Main Function @@ -39,11 +48,53 @@ Every application CLI first constructs a root command, then adds functionality b ### Root Command -The root command (also called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. - -* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). -* **Config** command from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. -* **Keys** commands from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command must include the following commands to support basic functionality in the application. + +* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](,,/core/node.md). The Status of a node includes [`NodeInfo`](https://github.com/tendermint/tendermint/blob/master/p2p/node_info.go#L75-L92), `SyncInfo` and `ValidatorInfo`: this information includes the node ID, latest block hash, and the validator public key and voting power. Here is an example of what the `status command` outputs: +```json +{ + "jsonrpc": "2.0", + "id": "", + "result": { + "node_info": { + "protocol_version": { + "p2p": "4", + "block": "7", + "app": "0" + }, + "id": "53729852020041b956e86685e24394e0bee4373f", + "listen_addr": "10.0.2.15:26656", + "network": "test-chain-Y1OHx6", + "version": "0.24.0-2ce1abc2", + "channels": "4020212223303800", + "moniker": "ubuntu-xenial", + "other": { + "tx_index": "on", + "rpc_addr": "tcp://0.0.0.0:26657" + } + }, + "sync_info": { + "latest_block_hash": "F51538DA498299F4C57AC8162AAFA0254CE08286", + "latest_app_hash": "0000000000000000", + "latest_block_height": "18", + "latest_block_time": "2018-09-17T11:42:19.149920551Z", + "catching_up": false + }, + "validator_info": { + "address": "D9F56456D7C5793815D0E9AF07C3A355D0FC64FD", + "pub_key": { + "type": "tendermint/PubKeyEd25519", + "value": "wVxKNtEsJmR4vvh651LrVoRguPs+6yJJ9Bz174gw9DM=" + }, + "voting_power": "10" + } + } +} +``` +* **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to. +The `config` command can be invoked by typing `appcli config` with optional arguments ` [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration. +* **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key. +For example, users can type `appcli keys add ` to add a new key and save an encrypted copy to disk, using the flag `--recover` to recover a private key from a seed phrase or the flag `--multisig` to group multiple keys together to create a multisig key. For full details on the `add` key command, see the code [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys/add.go). * [**Transaction**](#transaction-commands) commands. * [**Query**](#query-commands) commands. @@ -77,12 +128,12 @@ err := executor.Execute() ### Transaction Commands -[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes within modules. To enable the creation of transactions using the CLI interface, `TxCmd` should add the following commands: +[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md) that trigger state changes. To enable the creation of transactions using the CLI interface, `TxCmd` needs to add the following commands: -* **Sign** command from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, which signs messages in a transaction. To enable multisig, it should also add the `auth` module `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. -* **Broadcast** command from the SDK client tools, which broadcasts transactions. -* **Send** command from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. -* All commands in each module the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. +* **Sign** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_sign.go#L30-L83) from the [`auth`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/auth) module, the command that signs messages in a transaction. To enable multisig, add the `auth` module [`MultiSign`](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/tx_multisign.go#L26-L151) command. Since every transaction requires some sort of signature in order to be valid, this command is necessary for every application. +* **Broadcast** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/broadcast.go) from the SDK client tools, which broadcasts transactions. +* **Send** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/client/cli/tx.go#L31-L60) from the [`bank`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/bank) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions. +* All [module transaction commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetTxCmd()`](../building-modules/interfaces.md#GetTxCmd) on all the modules or using the Module Manager's [`AddTxCommands()`](../building-modules/module-manager.md) function. Here is an example of a `TxCmd` aggregating these subcommands from the [nameservice tutorial](https://cosmos.network/docs/tutorial). @@ -112,13 +163,13 @@ func txCmd(cdc *amino.Codec, mc []sdk.ModuleClients) *cobra.Command { ### Query Commands -[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` should add the following commands: +[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable basic queries, `QueryCmd` needs to add the following commands: -* **QueryTx** and/or other transaction query commands from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These various queries allow users to see if transactions have been included in a block. -* **Account** command from the `auth` module, which displays the state (e.g. account balance) of an account given an address. -* **Validator** command from the SDK rpc client tools, which displays the validator set of a given height. -* **Block** command from the SDK rpc client tools, which displays the block data for a given height. -* All commands in each module the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. +* **QueryTx** and/or other transaction [query commands](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go) from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block. +* **Account** [command](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/client/cli/query.go#L45-L73) from the `auth` module, which displays the state (e.g. account balance) of an account given an address. +* **Validator** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/validators.go) from the SDK rpc client tools, which displays the validator set of a given height. +* **Block** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/rpc/block.go) from the SDK rpc client tools, which displays the block data for a given height. +* All [module query commands](../building-modules/interfaces.md) the application is dependent on, retrieved by calling [`GetQueryCmd()`](../building-modules/interfaces.md#GetqueryCmd) on all the modules or using the Module Manager's `AddQueryCommands()` function. Here is an example of a `QueryCmd` aggregating subcommands, also from the nameservice tutorial (it is structurally identical to `TxCmd`): @@ -153,75 +204,49 @@ Flags are used to modify commands. Users can explicitly include them in commands A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -### Root Command Flags - -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go -rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") +const FlagFrom = "from" ``` -### Transaction Flags - -To **create** a transaction, the user enters a `tx` command and provides several flags. These are the basic flags added to every command using the SDK `./client/flags` package [`PostCommands`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function: - -* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. -* `--gas-adjustment` (optional) 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. -* `--gas-prices` 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. -* `--fees` specifies how much in fees the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. -* `--dry-run` (optional), similar to `--generate-only`, instructs the application to ignore the `--gas` flag and simulate the transaction running without broadcasting. -* `--indent` (optional) adds an indent to the JSON response. -* `--memo` sends a memo along with the transaction. +The flag can be added to a command `cmd`, adding a default value and description: -For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. - -```bash -appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json +```go +cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -To **sign** a transaction generated offline using the `--generate-only` flag, the user enters a `tx sign` command (by default, the transaction is automatically signed upon creation). There are four values for flags that must be provided if a transaction is expected to be signed: +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. -* `--from` specifies an address; the corresponding private key is used to sign the transaction. -* `--chain-id` specifies the unique identifier of the blockchain the transaction pertains to. -* `--sequence` is the value of a counter measuring how many transactions have been sent from the account. It is used to prevent replay attacks. -* `--account-number` is an identifier for the account. -* `--validate-signatures` (optional) instructs the process to sign the transaction and verify that all signatures have been provided. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S, which needs to be plugged in and unlocked. +### Root Command Flags -For example, the following command signs the inputted transaction, `myUnsignedTx.json`, and writes the signed transaction to the file `mySignedTx.json`. +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: -```bash -appcli tx sign myUnsignedTx.json --from --chain-id --sequence --account-number > mySignedTx.json +```go +rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") ``` -To **broadcast** a signed transaction generated offline, the user enters a `tx broadcast` command. Only one flag is required here: +### Transaction and Query Flags -* `--node` specifies which node to broadcast to. -* `--trust-node` (optional) indicates whether or not the node and its response proofs can be trusted. -* `--broadcast-mode` (optional) specifies when the process should return. Options include asynchronous (return immediately), synchronous (return after `CheckTx` passes), or block (return after block commit). +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. -For example, the following command broadcasts the signed transaction, `mySignedTx.json` to a particular node. +For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. ```bash -appcli tx broadcast mySignedTx.json --node +appcli tx send 1000uatom --from --gas auto -gas-prices 0.025uatom --generate-only > myUnsignedTx.json ``` -### Query Flags - -Queries also have flags. These are the basic flags added to every command using the SDK `./client/flags` package [`GetCommand`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function: +Here are the flags used: -* `--node` indicates which full-node to connect to. -* `--trust-node` (optional) represents whether or not the connected node is trusted. If the node is not trusted, all proofs in the responses are verified. -* `--indent` (optional) adds an indent to the JSON response. -* `--height` (optional) can be provided to query the blockchain at a specific height. -* `--ledger` (optional) lets the user perform the action using a Ledger Nano S. +* `--from` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `--gas` refers to how much [gas](../core/gas.md), which represents computational resources, Tx consumes. Gas is dependent on the computational needs of the transaction and is not precisely calculated until execution, but can be estimated by providing auto as the value for --gas. +* `--gas-prices` 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. +* `--generate-only` (optional) instructs the application to simply generate the unsigned transaction and output or write to a file. Without this flag, the transaction is created, signed, and broadcasted all in one command. ## Configurations -The last function to define is, `initConfig`, which should do exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` should do the following: +The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. From d861ad71c324606c8badb91e9c303c534d24c725 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:53:19 -0400 Subject: [PATCH 66/75] comments --- docs/building-modules/module-interfaces.md | 16 +++++++++ docs/interfaces/query-lifecycle.md | 38 +++++++++++++--------- docs/interfaces/rest.md | 35 ++++++++------------ 3 files changed, 52 insertions(+), 37 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index e4a1ff940713..f1136e63d72c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -183,8 +183,24 @@ type buyNameReq struct { Buyer string `json:"buyer"` } ``` + 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. +#### BaseReq + +`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. + +* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. +* `Memo` sends a memo along with the transaction. +* `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. +* `Gas` refers to how much [gas](../core/gas.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. +* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. +* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. + ### 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 [`CLIContext`](../interfaces/query-lifecycle.md#clicontext) created in the user interaction. diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 44026d16bc2d..7771e4398456 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -16,22 +16,30 @@ This document describes SDK interfaces in detail through the lifecycle of a quer ## Interfaces -A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by users of applications. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. +A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. For the purpose of explaining a query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module handles this query. But first, there are a few ways `Query` can be created by users. ### CLI -The main interface for an application is the command-line interface. Users connect to a full node and run the CLI directly from their machines. To create `Query` from their terminal, users type the following command: +The main interface for an application is the command-line interface. Users connect to a full-node and run the CLI directly from their machines - the CLI interacts directly with the full-node. To create `Query` from their terminal, users type the following command: -``` +```bash appcli query staking delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to), the user must use the `config` command to set them or provide them as flags. +Note that the general format is as follows: + +```bash +appcli query [moduleName] [command] --flag +``` + +To provide values such as `--node` (the full-node the CLI connects to), the user must use the `config` command to set them or provide them as flags. This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L253-L294). +The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there. + ### REST Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this: @@ -40,15 +48,15 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--chain-id` (the ID of the blockchain to make the query to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. -The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here]()). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. +The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -When users interact with the interfaces, the result is a CLI command or HTTP request. `Query` is then created when the command is executed or request handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. ## Request and Command Handling -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical. This section describes how the CLI command or HTTP request is processed, up until the ABCI request is sent. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. ### CLIContext @@ -65,27 +73,27 @@ For full specification of the `CLIContext` type, click [here](https://github.com ### Parameters and Route Creation -The next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. ### ABCI Query -The `CLIContext`'s main `Query` function takes the `route`, which is now called `path`, and arguments, now called `key`. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. ## Tendermint and ABCI -With a call to `ABCIQueryWithOptions()`, `Query` arrives at the consensus engine portion of its lifecycle. Nodes running the consensus engine (e.g. Tendermint Core) make ABCI calls to interact with the application. At this point, `Query` exists as an ABCI `RequestQuery` and the [ABCI Client](https://github.com/tendermint/tendermint/blob/master/abci/client/client.go#L16-L50) calls the ABCI method [`Query()`](https://tendermint.com/docs/spec/abci/abci.html#query) on the application. +With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). ## Application Query Handling -[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). +[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). -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. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. +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. 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). ## Response diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 858c4b9420a4..5f187d01ea8c 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,16 +7,20 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest). +This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). - [Application REST Interface](#application-rest-interface) -- [Request Types](#request-types) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) +- [Request Types](#request-types) ## Application REST Interface -Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface. +Building the REST Interface for an application involves creating a [REST server](./rest.md#rest-server) to route requests and output responses. The SDK has its own REST Server type used for [LCDs](../core/node.md) (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes()` function, starts up a new REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command in the `main()` function of the CLI interface: + +```go +rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) +``` Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this: @@ -24,26 +28,7 @@ Users can use the application CLI to start a new LCD, a local server through whi appcli rest-server --chain-id --trust-node ``` -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request `baseReq`, the name of the request, and any arguments for the transaction. - -### BaseReq -`BaseReq` is a type defined in the SDK that encapsulates much of the transaction configurations similar to CLI command flags. Users must provide the information in the body of their requests. - -* `From` indicates which [account](../core/accounts-fees.md) the transaction originates from. This account is used to sign the transaction. -* `Memo` sends a memo along with the transaction. -* `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. -* `Gas` refers to how much [gas](../core/gas.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. -* `Fees` specifies how much in [fees](../core/accounts-fees.md) the user is willing to pay in total. Note that the user only needs to provide either `gas-prices` or `fees`, but not both, because they can be derived from each other. -* `Simulate` instructs the application to ignore gas and simulate the transaction running without broadcasting. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. ## REST Server @@ -75,3 +60,9 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` + +## Request Types + +HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. + +Additionally, each request may contain arguments such as a specific address pertaining to the request. From a1546911e745d0f73505f38c99b1bcae4fe13d46 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 13 Aug 2019 23:54:43 -0400 Subject: [PATCH 67/75] minor edits --- docs/interfaces/query-lifecycle.md | 2 +- docs/interfaces/rest.md | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 7771e4398456..e6a0fa9f4ff4 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -48,7 +48,7 @@ Another interface through which users can make queries is through HTTP Requests GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations ``` -To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](./rest.md#basereq), the user must configure their local REST server with the values or provide them in the request body. +To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body. The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index 5f187d01ea8c..bf4a010d0fa8 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -12,7 +12,6 @@ This document describes how to create a REST interface for an SDK application. A - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) - [Registering Routes](#registering-routes) -- [Request Types](#request-types) ## Application REST Interface @@ -29,7 +28,6 @@ appcli rest-server --chain-id --trust-node ``` - ## REST Server A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following: @@ -60,9 +58,3 @@ This function is specific to the application and passed in to the `ServeCommand` ```go rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes)) ``` - -## Request Types - -HTTP Request types are defined by the module interfaces for every type of transaction. The structs all include a base request [`baseReq`](../building-modules/module-interfaces.md#basereq), the name of the request, and any arguments for the transaction. - -Additionally, each request may contain arguments such as a specific address pertaining to the request. From 3c7d671e0348493d953db2e6a362cabe3569d332 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Mon, 19 Aug 2019 19:31:02 -0700 Subject: [PATCH 68/75] better flow for query lifecycle --- docs/interfaces/query-lifecycle.md | 101 ++++++++++++++++++++++++----- 1 file changed, 85 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index e6a0fa9f4ff4..6c69aa454e68 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -8,13 +8,13 @@ This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `Query`. -- [Interfaces](#interfaces) -- [Request and Command Handling](#request-and-command-handling) -- [Tendermint and ABCI](#tendermint-and-abci) +- [Query Creation](#query-creation) +- [Query Preparation](#query-preparation) +- [RPC](#rpc) - [Application Query Handling](#application-query-handling) - [Response](#response) -## Interfaces +## Query Creation A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed; they can be fully handled by one full-node. @@ -52,11 +52,11 @@ To provide values such as `--node` (the full-node the CLI connects to) that are The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function (to see the handler itself, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/query.go#L103-L106)). Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters. -To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` is then created when the command is executed or HTTP request is handled. +To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node. -## Request and Command Handling +## Query Preparation -The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing heavily involves a `CLIContext`. +The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing happens within the CLI or REST server and heavily involves a `CLIContext`. ### CLIContext @@ -69,23 +69,69 @@ The first thing that is created in the execution of a CLI command is a `CLIConte * **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response. * **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response. -For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). +The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node. For full specification of the `CLIContext` type, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/context.go#L36-L59). -### Parameters and Route Creation -The first step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. -**Arguments:** In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +### Arguments and Route Creation -**Route:** A `route` is also created for `Query` so that the application will understand which module to route the query to. [Baseapp](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking` with the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. -### ABCI Query +#### Parse Arguments -The `CLIContext`'s main `Query` function takes the `route` and arguments. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. -## Tendermint and ABCI +Here is what the code looks like for the CLI command: -With a call to `ABCIQueryWithOptions()`, `Query` is received by a full-node which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. +```go +delAddr, err := sdk.AccAddressFromBech32(args[0]) +bz, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr)) +``` + +Here is what the code looks like for the HTTP Request: + +```go +vars := mux.Vars(r) +bech32delegator := vars["delegatorAddr"] +delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator) +cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) +if !ok { + return +} +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"`. + +Here is what the code looks like: + +```go +route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorDelegations) +``` + +Now, `Query` exists as a set of encoded arguments and a route to a specific module and its query type. It is ready to be relayed to a full-node. + +#### ABCI Query Call + +The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`. + +Here is what the code looks like (for full specification of all `CLIContext` query functionality, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go)): + +```go +node, err := ctx.GetNode() +opts := rpcclient.ABCIQueryOptions{ + Height: ctx.Height, + Prove: !ctx.TrustNode, +} +result, err := node.ABCIQueryWithOptions(path, key, opts) +``` + +## RPC + +With a call to `ABCIQueryWithOptions()`, `Query` is received by a [full-node](../core/encoding.md) which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon. Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc). @@ -103,10 +149,33 @@ Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.R The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. +Here is what the code looks like: + +```go +res, _, err := cliCtx.QueryWithData(route, bz) +var resp types.DelegationResponses +if err := cdc.UnmarshalJSON(res, &resp); err != nil { + return err +} +return cliCtx.PrintOutput(resp) +``` + ### REST Response The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. +Here is what the code looks like: + +```go +res, height, err := cliCtx.QueryWithData(endpoint, bz) +if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return +} +cliCtx = cliCtx.WithHeight(height) +rest.PostProcessResponse(w, cliCtx, res) +``` + ## Next Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md). From 463bffa63416969bf750b8597ee54e502c7f1ecf Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:28:34 -0700 Subject: [PATCH 69/75] checkout master-docs files --- docs/.vuepress/config.js | 3 +- docs/basics/app-anatomy.md | 94 +++++++--------- docs/building-modules/intro.md | 29 ++--- docs/core/baseapp.md | 165 +++++++++++------------------ docs/core/node.md | 2 +- docs/intro/README.md | 15 +-- docs/intro/sdk-app-architecture.md | 26 ++--- docs/intro/why-app-specific.md | 39 +++---- 8 files changed, 155 insertions(+), 218 deletions(-) diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 602d20781420..9ee6a31059c5 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -31,8 +31,7 @@ module.exports = { "/intro/", "/intro/why-app-specific", "/intro/sdk-app-architecture", - "/intro/sdk-design", - "/intro/ocap" + "/intro/sdk-design" ] }, { diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index 2e4613c5e8b6..dc58e389342a 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,9 +55,9 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](../core/node.md#main-function). +To learn more about the `main.go` function, [click here](./node.md#main-function). -Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](#constructor-function-(`appCreator`)) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. +Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. The `start` command function primarily does three things: @@ -65,8 +65,6 @@ The `start` command function primarily does three things: 2. Initialize the state-machine with the latest known state, extracted from the `db` stored in the `~/.appd/data` folder. At this point, the state-machine is at height `appBlockHeight`. 3. Create and start a new Tendermint instance. Among other things, the node will perform a handshake with its peers. It will get the latest `blockHeight` from them, and replay blocks to sync to this height if it is greater than the local `appBlockHeight`. If `appBlockHeight` is `0`, the node is starting from genesis and Tendermint sends an `InitChain` message via the ABCI to the `app`, which triggers the [`InitChainer`](#initchainer). -To learn more about the `start` command, [click here](../core/node.md#start-command). - ## Core Application File In general, the core of the state-machine is defined in a file called `app.go`. It mainly contains the **type definition of the application** and functions to **create and initialize it**. @@ -75,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -87,17 +85,16 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: -- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. - Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - + [`InitChainer`](#initchainer): used to initialize the application when it is first started. - + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. + - [`InitChainer`](#initchainer): used to initialize the application when it is first started. + - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. - Mount the stores. - Return the application. @@ -107,7 +104,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -119,40 +116,39 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). ### Register Codec -The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. [amino](./amino.md)) initiliaze the codec of the SDK and each of the application's modules using the `RegisterCodec` function. +The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). - -To learn more about modules, [click here](./modules.md) +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: -To learn more about the application module interface, [click here](./modules.md#application-module-interface). -======= -To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ->>>>>>> workinnn +- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). +- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. +- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. +- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. +- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. ### Message Types -A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. 2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. 3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. 4. If the message is successfully processed, the state is updated. @@ -161,24 +157,20 @@ For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. -To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). - ### Handler -The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). - **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. -To learn more about handlers, [click here](../building-modules/handler.md). - ### Keeper -[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -192,18 +184,14 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -To learn more about `keepers`, [click here](../building-modules/keeper.md). - ### Querier -[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). - -To learn more about `queriers`, [click here](../building-modules/querier.md). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). ### Command-Line and REST Interfaces @@ -216,11 +204,9 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). -To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). - #### REST -The module's REST interface 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 lets users generate transactions and query the state through REST calls to the application's light client daemon (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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -228,23 +214,19 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). -To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). - ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. - **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). -To learn more about interfaces, [click here](../interfaces/intro.md). - ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/intro.md b/docs/building-modules/intro.md index d3e8440992d5..403eb755a2a2 100644 --- a/docs/building-modules/intro.md +++ b/docs/building-modules/intro.md @@ -7,7 +7,7 @@ ## Synopsis -Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. +Modules define most of the logic of any SDK application. Developers compose module together to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management. - [Role of Modules in an SDK application](#role-of-modules-in-an-sdk-application) - [How to Approach Building Modules as a Developer](#how-to-approach-building-modules-as-a-developer) @@ -18,14 +18,14 @@ Modules define most of the logic of any SDK application. Developers compose modu The Cosmos SDK can be thought as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application need, like a boilerplate implementation of the ABCI to communicate with the underlying consensus engine, a multistore to persist state, a server to form a full-node and interfaces to handle queries. -On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. +On top of this core, the SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source SDK modules, making it increasingly easier to build complex blockchain applications. -SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. +SDK Modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one ore multiple `KVStore` in the [main multistore](../core/store.md), as well as a subset of [`message` types](./message.md). These `message`s are routed by one of the main component of SDK core, [`baseapp`](../core/baseapp.md), to the [`handler`](./handler.md) of the module that define them. ``` + | - | Transaction relayed from the full-node's consensus engine + | Transaction relayed from the full-node's consensus engine | to the node's application via DeliverTx | | @@ -67,28 +67,29 @@ SDK Modules can be seen as little state-machines within the state-machine. They v ``` -As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. +As a result of this architecture, building an SDK application usually revolves around writing modules to implement the specialized logic of the application, and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts or token management. ## How to Approach Building Modules as a Developer While there is no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them: -- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). -- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. -- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. +- **Composability**: SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./keeper.md). +- **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concern enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../core/ocap.md) of the Cosmos SDK. +- **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some module to be malicious. That is why module developers need to carefully think not only about how their module interracts with other modules, and how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`. ## Main Components of SDK Module -Modules generally share the same core components: +Modules are by convention defined in the `.x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components: -- Custom [`message` types](./message.md) 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. +- Custom [`message` types](./message.md) 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). - 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 `module` interface in order to be managed by the [`module manager`](./module-manager.md). +In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./module-manager.md). ## Next -Read more on the [`module interface` and the `module manager`](./module-manager.md) +Read more on the [`AppModule` interface and the `module manager`](./module-manager.md) + diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 44c46f26f489..6c3d2dd9e506 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. +This document describes `baseapp`, the abstraction that implements most of the common functionalities of an SDK application. - [Introduction](#introduction) - [Type Definition](#type-definition) @@ -17,7 +17,7 @@ This document describes `baseapp`, the abstraction that implements most of the c - [Main ABCI Messages](#abci) + [CheckTx](#checktx) + [DeliverTx](#delivertx) -- [RunTx, AnteHandler and RunMsgs](#runtx-,antehandler-and-runmsgs) +- [RunTx, AnteHandler and RunMsgs](#runtx-antehandler-and-runmsgs) + [RunTx](#runtx) + [AnteHandler](#antehandler) + [RunMsgs](#runmsgs) @@ -28,18 +28,18 @@ This document describes `baseapp`, the abstraction that implements most of the c + [Commit](#commit) + [Info](#info) + [Query](#query) - + ## Introduction `baseapp` is an abstraction that implements the core of an SDK application, namely: -- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). +- The [Application-Blockchain Interface](#abci), for the state-machine to communicate with the underlying consensus engine (e.g. Tendermint). - A [Router](#routing), to route [messages](./tx-msgs.md) and [queries](./querier.md) to the appropriate [module](../building-modules/intro.md). -- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. +- Different [states](#states), as the state-machine can have different parallel states updated based on the ABCI message received. The goal of `baseapp` is to provide a boilerplate SDK application that developers can easily extend to build their own custom application. Usually, developers will create a custom type for their application, like so: -```go +```go type app struct { *bam.BaseApp // reference to baseapp cdc *codec.Codec @@ -52,24 +52,24 @@ type app struct { } ``` -Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. +Extending the application with `baseapp` gives the former access to all of `baseapp`'s methods. This allows developers to compose their custom application with the modules they want, while not having to concern themselves with the hard work of implementing the ABCI, the routing and state management logic. ## Type Definition The [`baseapp` type](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) holds many important parameters for any Cosmos SDK based application. Let us go through the most important components. -*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* +*Note: Not all parameters are described, only the most important ones. Refer to the [type definition](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L45-L91) for the full list* First, the important parameters that are initialized during the initialization of the application: -- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. +- A [`CommitMultiStore`](./store.md#commit-multi-store). This is the main store of the application, which holds the canonical state that is committed at the [end of each block](#commit). This store is **not** cached, meaning it is not used to update the application's intermediate (un-committed) states. The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. - A [database](./store.md#database) `db`, which is used by the `CommitMultiStore` to handle data storage. - A [router](#message-routing). The `router` facilitates the routing of [messages](../building-modules/messages-and-queries.md#messages) to the appropriate module for it to be processed. - A [query router](#query-routing). The `query router` facilitates the routing of [queries](../building-modules/messages-and-queries.md#queries) to the appropriate module for it to be processed. - A [`txDecoder`](https://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder), used to decode transaction `[]byte` relayed by the underlying Tendermint engine. - A [`baseKey`], to access the [main store](./store.md#main-store) in the `CommitMultiStore`. The main store is used to persist data related to the core of the application, like consensus parameters. - A [`anteHandler`](#antehandler), to handle signature verification and fee paiement when a transaction is received. -- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. +- An [`initChainer`](../basics/app-anatomy.md#initchainer), [`beginBlocker` and `endBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker), which are the functions executed when the application received the [InitChain], [BeginBlock] and [EndBlock] messages from the underlying Tendermint engine. Then, parameters used to define [volatile states](#volatile-states) (i.e. cached states): @@ -84,13 +84,13 @@ Finally, a few more important parameterd: ## Constructor -`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. +`NewBaseApp(name string, logger log.Logger, db dbm.DB, txDecoder sdk.TxDecoder, options ...func(*BaseApp),)` is the constructor function for `baseapp`. It is called from the [application's constructor function](../basics/app-anatomy.md#constructor-function) each time the full-node is started. -`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. +`baseapp`'s constructor function is pretty straightforward. The only thing worth noting is the possibility to add additional [`options`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go) to `baseapp` by passing `options functions` to the constructor function, which will execute them in order. `options` are generally `setters` function for important parameters, like `SetPruning()` to active pruning or `SetMinGasPrices()` to set the node's `min-gas-prices`. -A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. +A list of `options` example can be found [here](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/options.go). Naturally, developers can add additional `options` based on their application's needs. -## States +## States `baseapp` handles various parallel states for different purposes. There is the [main state](#main-state), which is the canonical state of the application, and volatile states like [`checkState`](#checkState) and [`deliverState`](#deliverstate), which are used to handle temporary states inbetween updates of the main state. @@ -120,54 +120,7 @@ DeliverTx(tx1) | | | +----------------------+ +----------------------+ | | | | | DeliverState(t)(1) | | | | | +----------------------+ | | -DeliverTx(tx2) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(2) | | | - | | +----------------------+ | | -DeliverTx(tx3) | | | | | - | | v | | - | | +----------------------+ | | - | | | DeliverState(t)(3) | | | - +----------------------+ +----------------------+ +----------------------+ -Commit() | | | - v v v - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t+1)(0) | | DeliverState(t+1)(0) | | QueryState(t+1) | - +----------------------+ | | | | - . . . - . . . - . . . - -``` - -``` - To perform stateful checks To execute state To serve queries - on received transactions transitions during DeliverTx on last-committed state - +----------------------+ +----------------------+ +----------------------+ - | CheckState(t)(0) | | DeliverState(t)(0) | | QueryState(t) | - +----------------------+ | | | | -CheckTx(tx1) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(1) | | | | | - +----------------------+ | | | | -CheckTx(tx2) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(2) | | | | | - +----------------------+ | | | | -CheckTx(tx3) | | | | | - v | | | | - +----------------------+ | | | | - | CheckState(t)(3) | | | | | - +----------------------+ +----------------------+ | | -DeliverTx(tx1) | | | | - v v | | - +----------------------+ +----------------------+ | | - | | | DeliverState(t)(1) | | | - | | +----------------------+ | | -DeliverTx(tx2) | | | | | +DeliverTx(tx2) | | | | | | | v | | | | +----------------------+ | | | | | DeliverState(t)(2) | | | @@ -185,12 +138,12 @@ Commit() | | . . . . . . . . . - + ``` ### Main State -The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. +The main state is the canonical state of the application. It is initialized on [`InitChain`](#initchain and updated on [`Commit`](#abci-commit) at the end of each block. ``` +--------+ +--------+ @@ -206,13 +159,13 @@ The main state is held by `baseapp` in a structure called the [`CommitMultiStore Volatile - or cached - states are used in between [`Commit`s](#commit) to manage temporary states. They are reset to the latest version of the main state after it is committed. There are two main volatile states: -- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). +- `checkState`: This cached state is initialized during [`InitChain`](#initchain), updated during [`CheckTx`](#abci-checktx) when an unconfirmed transaction is received, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). - `deliverState`: This cached state is initialized during [`BeginBlock`](#beginblock), updated during [`DeliverTx`](#abci-delivertx) when a transaction included in a block is processed, and reset to the [main state](#main-state) on [`Commit`](#abci-commit). Both `checkState` and `deliverState` are of type [`state`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L973-L976), which includes: -- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. -- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. +- A [`CacheMultiStore`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go), which is a cached version of the main `CommitMultiStore`. A new version of this store is committed at the end of each successful `CheckTx`/`DeliverTx` execution. +- A [`Context`](./context.md), which carries general information (like raw transaction size, block height, ...) that might be needed in order to process the transaction during `CheckTx` and `DeliverTx`. The `context` also holds a cache-wrapped version of the `CacheMultiStore`, so that the `CacheMultiStore` can maintain the correct version even if an internal step of `CheckTx` or `DeliverTx` fails. ## Routing @@ -222,24 +175,24 @@ When messages and queries are received by the application, they must be routed t [`Message`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) ABCI messages. To do so, `baseapp` holds a [`router`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/router.go) which maps `paths` (`string`) to the appropriate module [`handler`](./handler.md). Usually, the `path` is the name of the module. -The application's `router` is initilalized with all the 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). +The application's `router` is initilalized with all the 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). ### 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. +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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/queryrouter.go), which maps `paths` (`string`) to the appropriate module `querier`. Usually, the `path` is the name of the module. 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). ## Main ABCI Messages -The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. +The [Application-Blockchain Interface](https://tendermint.com/docs/spec/abci/) (ABCI) is a generic interface that connects a state-machine with a consensus engine to form a functional full-node. It can be wrapped in any language, and needs to be implemented by each application-specific blockchain built on top of an ABCI-compatible consensus engine like Tendermint. The consensus engine handles two main tasks: - The networking logic, which mainly consists in gossiping block parts, transactions and consensus votes. -- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. +- The consensus logic, which results in the deterministic ordering of transactions in the form of blocks. -It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. +It is **not** the role of the consensus engine to define the state or the validity of transactions. Generally, transactions are handled by the consensus engine in the form of `[]bytes`, and relayed to the application via the ABCI to be decoded and processed. At keys moments in the networking and consensus processes (e.g. beginning of a block, commit of a block, reception of an unconfirmed transaction, ...), the consensus engine emits ABCI messages for the state-machine to act on. Developers building on top of the Cosmos SDK need not implement the ABCI themselves, as `baseapp` comes with a built-in implementation of the interface. Let us go through the main ABCI messages that `baseapp` implements: [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) @@ -251,43 +204,43 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel 1. Extract the `message`s from the transaction. 2. Perform *stateless* checks by calling `ValidateBasic()` on each of the `messages`. This is done first, as *stateless* checks are less computationally expensive than *stateful* checks. If `ValidateBasic()` fail, `CheckTx` returns before running *stateful* checks, which saves resources. -3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. -4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. +3. Perform non-module related *stateful* checks on the account. This step is mainly about checking that the `message` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](./accounts-fees-gas.md#gas) counting occurs here, as `message`s are not processed. Usually, the [`anteHandler`](./accounts-fees-gas.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. +4. Ensure that a [`Route`](#message-routing) exists for each `message`, but do **not** actually process `message`s. `Message`s only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-,antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). +Steps 2. and 3. are performed by the [`anteHandler`](./accounts-fees-gas.md#antehandler) in the [`RunTx`](#runtx-antehandler-and-runmsgs) function, which `CheckTx` calls with the `runTxModeCheck` mode. During each step of `CheckTx`, a special [volatile state](#volatile-states) called `checkState` is updated. This state is used to keep track of the temporary changes triggered by the `CheckTx` calls of each transaction without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx`, the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx` and be rejected. In any case, the sender's account will not actually pay the fees until the transaction is actually included in a block, because `checkState` never gets committed to the main state. `checkState` is reset to the latest state of the main state each time a blocks gets [committed](#commit). `CheckTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `CheckTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example). - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. ### DeliverTx -When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. +When the underlying consensus engine receives a block proposal, each transaction in the block needs to be processed by the application. To that end, the underlying consensus engine sends a `DeliverTx` message to the application for each transaction in a sequential order. -Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. +Before the first transaction of a given block is processed, a [volatile state](#volatile-states) called `deliverState` is intialized during [`BeginBlock`](#beginblock). This state is updated each time a transaction is processed via `DeliverTx`, and committed to the [main state](#main-state) when the block is [committed](#commit), after what is is set to `nil`. `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. -5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. +3. The `anteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +5. For each `message` in the transaction, route to the appropriate module's [`handler`](../building-modules/handler.md). Additional *stateful* checks are performed, and the cache-wrapped multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `handler` returns successfully, the cache-wrapped multistore held in `context` is written to `deliverState` `CacheMultiStore`. -During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. +During step 5., each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation [here](https://github.com/cosmos/cosmos-sdk/blob/master/store/types/gas.go#L142-L150). At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. `DeliverTx` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://tendermint.com/docs/spec/abci/abci.html#messages). The response contains: -- `Code (uint32)`: Response Code. `0` if successful. +- `Code (uint32)`: Response Code. `0` if successful. - `Data ([]byte)`: Result bytes, if any. - `Log (string):` The output of the application's logger. May be non-deterministic. - `Info (string):` Additional information. May be non-deterministic. -- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. -- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. +- `GasWanted (int64)`: Amount of gas requested for transaction. It is provided by users when they generate the transaction. +- `GasUsed (int64)`: Amount of gas consumed by transaction. During `DeliverTx`, this value is computed by multiplying the standard cost of a transaction byte by the size of the raw transaction (click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go#L101) for an example), and by adding gas each time a read/write to the store occurs. - `Tags ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). - `Codespace (string)`: Namespace for the Code. @@ -295,13 +248,13 @@ During step 5., each read/write to the store increases the value of `GasConsumed ### RunTx -`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a cached version of the main store instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](./accounts-fees-gas.md#gas) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. -After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. +After that, `RunTx` calls `ValidateBasic()` on each `message`in the `Tx`, which runs prelimary *stateless* validity checks. If any `message` fails to pass `ValidateBasic()`, `RunTx` returns with an error. -Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the [`cacheTxContext()`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L781-L798) function. This allows `RunTx` not to commit the changes made to the state during the execution of `anteHandler` if it ends up failing. It also prevents the module implementing the `anteHandler` from writing to state, which is an important part of the [object-capabilities](./ocap.md) of the Cosmos SDK. Finally, the [`RunMsgs`](#runmsgs) function is called to process the `messages`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are cached-wrapped using the `cacheTxContext()` function. @@ -311,17 +264,17 @@ The `AnteHandler` is a special handler that implements the [`anteHandler` interf The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: -- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. -- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. -- Play a role in the incentivisation of stakeholders via the collection of transaction fees. +- Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./tx-msgs.md#sequence) checking. +- Perform preliminary *stateful* validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. +- Play a role in the incentivisation of stakeholders via the collection of transaction fees. `baseapp` holds an `anteHandler` as paraemter, which is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` today is that of the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/master/x/auth/ante.go). ### RunMsgs -`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `message`s. -First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. +First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then, using the application's [`router`](#routing) and the `route`, it checks for the existence of a `handler`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. If instead `mode == runTxModeDeliver`, the [`handler`](../building-modules/handler.md) function for the message is executed, before `RunMsgs` returns. ## Other ABCI Messages @@ -329,9 +282,9 @@ First, it retreives the `message`'s `route` using the `Msg.Route()` method. Then The [`InitChain` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#initchain) is sent from the underlying Tendermint engine when the chain is first started. It is mainly used to **initialize** parameters and state like: -- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. +- [Consensus Parameters](https://tendermint.com/docs/spec/abci/apps.html#consensus-parameters) via `setConsensusParams`. - [`checkState` and `deliverState`](#volatile-states) via `setCheckState` and `setDeliverState`. -- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. +- The [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter), with infinite gas to process genesis transactions. Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls the [`initChainer()`](../basics/app-anatomy.md#initchainer) of the application in order to initialize the main state of the application from the [`genesis file`](./genesis.md) and, if defined, call the `InitGenesis` function of each of the application's modules. @@ -339,37 +292,37 @@ Finally, the `InitChain(req abci.RequestInitChain)` method of `baseapp` calls th The [`BeginBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#beginblock) is sent from the underlying Tendermint engine when a block proposal created by the correct proposer is received, before [`DeliverTx`](#delivertx) is run for each transaction in the block. It allows developers to have logic be executed at the beginning of each block. In the Cosmos SDK, the `BeginBlock(req abci.RequestBeginBlock)` method does the following: -- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. -- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. +- Initialize [`deliverState`](#volatile-states) with the latest header using the `req abci.RequestBeginBlock` passed as parameter via the [`setDeliverState`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L283-L289) function. +- Initialize the [block gas meter](../basics/accounts-fees-gas.md#block-gas-meter) with the `maxGas` limit. The `gas` consumed within the block cannot go above `maxGas`. This parameter is defined in the application's consensus parameters. - Run the application's [`begingBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `BeginBlocker()` method of each of the application's modules. - Set the [`VoteInfos`](https://tendermint.com/docs/app-dev/abci-spec.html#voteinfo) of the application, i.e. the list of validators whose *precommit* for the previous block was included by the proposer of the current block. This information is carried into the [`Context`](./context.md) so that it can be used during `DeliverTx` and `EndBlock`. ### EndBlock -The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. +The [`EndBlock` ABCI message](#https://tendermint.com/docs/app-dev/abci-spec.html#endblock) is sent from the underlying Tendermint engine after [`DeliverTx`](#delivertx) as been run for each transactioni n the block. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk `EndBlock(req abci.RequestEndBlock)` method is to run the application's [`endBlocker()`](../basics/app-anatomy.md#beginblocker-and-endblock), which mainly runs the `EndBlocker()` method of each of the application's modules. ### Commit -The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. +The [`Commit` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#commit) is sent from the underlying Tendermint engine after the full-node has received *precommits* from 2/3+ of validators (weighted by voting power). On the `baseapp` end, the `Commit(res abci.ResponseCommit)` function is implemented to commit all the valid state transitions that occured during `BeginBlock`, `DeliverTx` and `EndBlock` and to reset state for the next block. To commit state-transitions, the `Commit` function calls the `Write()` function on `deliverState.ms`, where `deliverState.ms` is a cached multistore of the main store `app.cms`. Then, the `Commit` function sets `checkState` to the latest header (obtbained from `deliverState.ctx.BlockHeader`) and `deliverState` to `nil`. -Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. +Finally, `Commit` returns the hash of the commitment of `app.cms` back to the underlying consensus engine. This hash is used as a reference in the header of the next block. ### Info -The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. +The [`Info` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#info) is a simple query from the underlying consensus engine, notably used to sync the latter with the application during a handshake that happens on startup. When called, the `Info(res abci.ResponseInfo)` function from `baseapp` will return the application's name, version and the hash of the last commit of `app.cms`. -### Query +### Query -The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). +The [`Query` ABCI message](https://tendermint.com/docs/app-dev/abci-spec.html#query) is used to serve queries received from the underlying consensus engine, including queries received via RPC like Tendermint RPC. It is the main entrypoint to build interfaces with the application. The application must respect a few rules when implementing the `Query` method, which are outlined [here](https://tendermint.com/docs/app-dev/abci-spec.html#query). The `baseapp` implementation of the `Query(req abci.RequestQuery)` method is a simple dispatcher serving 4 main categories of queries: - Application-related queries like querying the application's version, which are served via the `handleQueryApp` method. -- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. +- Direct queries to the multistore, which are served by the `handlerQueryStore` method. These direct queryeis are different from custom queries which go through `app.queryRouter`, and are mainly used by third-party service provider like block explorers. - P2P queries, which are served via the `handleQueryP2P` method. These queries return either `app.addrPeerFilter` or `app.ipPeerFilter` that contain the list of peers filtered by address or IP respectively. These lists are first initialized via `options` in `baseapp`'s [constructor](#constructor). -- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). +- Custom queries, which encompass most queries, are served via the `handleQueryCustom` method. The `handleQueryCustom` cache-wraps the multistore before using the `queryRoute` obtained from [`app.queryRouter`](#query-routing) to map the query to the appropriate module's [`querier`](../building-modules/querier.md). ## Next diff --git a/docs/core/node.md b/docs/core/node.md index 36fe12602d0d..85c6152542ad 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -2,7 +2,7 @@ ## Pre-Requisite Reading -## main function +## `main` function TODO diff --git a/docs/intro/README.md b/docs/intro/README.md index e676fd179b16..9df4e13e443c 100644 --- a/docs/intro/README.md +++ b/docs/intro/README.md @@ -2,15 +2,15 @@ ## What is the SDK? -The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissionned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. +The [Cosmos-SDK](https://github.com/cosmos/cosmos-sdk) is an open-source framework for building multi-asset public Proof-of-Stake (PoS) blockchains, like the Cosmos Hub, as well as permissioned Proof-Of-Authority (PoA) blockchains. Blockchains built with the Cosmos SDK are generally referred to as **application-specific blockchains**. -The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developer to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). +The goal of the Cosmos SDK is to allow developers to easily create custom blockchains from scratch that can natively interoperate with other blockchains. We envision the SDK as the npm-like framework to build secure blockchain applications on top of [Tendermint](https://github.com/tendermint/tendermint). SDK-based blockchains are built out of composable modules, most of which are open source and readily available for any developers to use. Anyone can create a module for the Cosmos-SDK, and integrating already-built modules is as simple as importing them into your blockchain application. What's more, the Cosmos SDK is a capabilities-based system, which allows developers to better reason about the security of interactions between modules. For a deeper look at capabilities, jump to [this section](./ocap.md). ## What are Application-Specific Blockchains? One development paradigm in the blockchain world today is that of virtual-machine blockchains like Ethereum, where development generally revolves around building a decentralised applications on top of an existing blockchain as a set of smart contracts. While smart contracts can be very good for some use cases like single-use applications (e.g. ICOs), they often fall short for building complex decentralised platforms. More generally, smart contracts can be limiting in terms of flexibility, sovereignty and performance. -Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. +Application-specific blockchains offer a radically different development paradigm than virtual-machine blockchains. An application-specific blockchain is a blockchain customized to operate a single application: developers have all the freedom to make the design decisions required for the application to run optimally. They can also provide better sovereignty, security and performance. To learn more about application-specific blockchains, [click here](./why-app-specific.md). @@ -18,12 +18,13 @@ To learn more about application-specific blockchains, [click here](./why-app-spe The Cosmos SDK is the most advanced framework for building custom application-specific blockchains today. Here are a few reasons why you might want to consider building your decentralised application with the Cosmos SDK: -- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used accross the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. -- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. -- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. -- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [Iris](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). +- The default consensus engine available within the SDK is [Tendermint Core](https://github.com/tendermint/tendermint). Tendermint is the most (and only) mature BFT consensus engine in existence. It is widely used across the industry and is considered the gold standard consensus engine for building Proof-of-Stake systems. +- The SDK is open source and designed to make it easy to build blockchains out of composable modules. As the ecosystem of open source SDK modules grow, it will become increasingly easier to build complex decentralised platforms with it. +- The SDK is inspired by capabilities-based security, and informed by years of wrestling with blockchain state-machines. This makes the Cosmos SDK a very secure environment to build blockchains. +- Most importantly, the Cosmos SDK has already been used to build many application-specific blockchains that are already in production. Among others, we can cite [Cosmos Hub](https://hub.cosmos.network), [IRIS Hub](https://irisnet.org), [Binance Chain](https://docs.binance.org/), [Terra](https://terra.money/) or [Lino](https://lino.network/). Many more are building on the Cosmos SDK. You can get a view of the ecosystem [here](https://cosmos.network/ecosystem). ## Getting started with the Cosmos SDK - Learn more about the [architecture of an SDK application](./sdk-app-architecture.md) - Learn how to build an application-specific blockchain from scratch with the [SDK Tutorial](https://cosmos.network/docs/tutorial) + diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index a420fe627c33..94007a2742dc 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -1,12 +1,12 @@ # SDK Application Architecture -## State machine +## State machine -At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). +At its core, a blockchain is a [replicated deterministic state machine](https://en.wikipedia.org/wiki/State_machine_replication). -A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. +A state machine is a computer science concept whereby a machine can have multiple states, but only one at any given time. There is a `state`, which describes the current state of the system, and `transactions`, that trigger state transitions. -Given a state S and a transaction T, the state machine will return a new state S'. +Given a state S and a transaction T, the state machine will return a new state S'. ``` +--------+ +--------+ @@ -26,9 +26,9 @@ In practice, the transactions are bundled in blocks to make the process more eff +--------+ +--------+ ``` -In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. +In a blockchain context, the state machine is deterministic. This means that if you start at a given state and replay the same sequence of transactions, you will always end up with the same final state. -The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. +The Cosmos SDK gives you maximum flexibility to define the state of your application, transaction types and state transition functions. The process of building the state-machine with the SDK will be described more in depth in the following sections. But first, let us see how it is replicated using **Tendermint**. ### Tendermint @@ -54,14 +54,14 @@ Blockchain node | | Consensus | | Tendermint is an application-agnostic engine that is responsible for handling the *networking* and *consensus* layers of your blockchain. In practice, this means that Tendermint is responsible for propagating and ordering transaction bytes. Tendermint Core relies on an eponymous Byzantine-Fault-Tolerant (BFT) algorithm to reach consensus on the order of transactions. For more on Tendermint, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html). -Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). +The Tendermint consensus algorithm works with a set of special nodes called *Validators*. Validators are responsible for adding blocks of transactions to the blockchain. At any given block, there is a validator set V. A validator in V is chosen by the algorithm to be the proposer of the next block. This block is considered valid if more than two thirds of V signed a *[prevote](https://tendermint.com/docs/spec/consensus/consensus.html#prevote-step-height-h-round-r)* and a *[precommit](https://tendermint.com/docs/spec/consensus/consensus.html#precommit-step-height-h-round-r)* on it, and if all the transactions that it contains are valid. The validator set can be changed by rules written in the state-machine. For a deeper look at the algorithm, click [here](https://tendermint.com/docs/introduction/what-is-tendermint.html#consensus-overview). -The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. +The main part of a Cosmos SDK application is a blockchain daemon that is run by each node in the network locally. If less than one third of the *validator set* is byzantine (i.e. malicious), then each node should obtain the same result when querying the state at the same time. ## ABCI -Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. +Tendermint passes transactions from the network to the application through an interface called the [ABCI](https://github.com/tendermint/tendermint/tree/master/abci), which the application must implement. ``` +---------------------+ @@ -81,16 +81,16 @@ Tendermint passes transactions from the network to the application through an in +---------------------+ ``` -Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. +Note that **Tendermint only handles transaction bytes**. It has no knowledge of what these bytes mean. All Tendermint does is order these transaction bytes deterministically. Tendermint passes the bytes to the application via the ABCI, and expects a return code to inform it if the messages contained in the transactions were successfully processed or not. Here are the most important messages of the ABCI: -- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +- `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam. A special handler called the "Ante Handler" is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the check is valid, the transaction is added to the [mempool](https://tendermint.com/docs/spec/reactors/mempool/functionality.html#mempool-functionality) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. - `DeliverTx`: When a [valid block](https://tendermint.com/docs/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the given block is passed to the application via `DeliverTx` to be processed. It is during this stage that the state transitions occur. The "Ante Handler" executes again along with the actual handlers for each message in the transaction. - - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. + - `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transaction or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. For a more detailed view of the ABCI methods and types, click [here](https://tendermint.com/docs/spec/abci/abci.html#overview). Any application built on Tendermint needs to implement the ABCI interface in order to communicate with the underlying local Tendermint engine. Fortunately, you do not have to implement the ABCI interface. The Cosmos SDK provides a boilerplate implementation of it in the form of [baseapp](./sdk-design.md#baseapp). -### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) +### Next, let us go into the [high-level design principles of the SDK](./sdk-design.md) \ No newline at end of file diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index 0873f87d0e4a..1b160429f6eb 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -4,7 +4,7 @@ This document explains what application-specific blockchains are, and why develo ## What are application-specific blockchains? -Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. +Application-specific blockchains are blockchains customized to operate a single application. Instead of building a decentralised application on top of an underlying blockchain like Ethereum, developers build their own blockchain from the ground up. This means building a full-node client, a light-client, and all the necessary interfaces (CLI, REST, ...) to interract with the nodes. ``` ^ +-------------------------------+ ^ @@ -24,13 +24,13 @@ Blockchain node | | Consensus | | ## What are the shortcomings of Smart Contracts? -Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. +Virtual-machine blockchains like Ethereum addressed the demand for more programmability back in 2014. At the time, the options available for building decentralised applications were quite limited. Most developers would build on top of the complex and limited Bitcoin scripting language, or fork the Bitcoin codebase which was hard to work with and customize. Virtual-machine blockchains came in with a new value proposition. Their state-machine incorporates a virtual-machine that is able to interpret turing-complete programs called Smart Contracts. These Smart Contracts are very good for use cases like one-time events (e.g. ICOs), but they can fall short for building complex decentralised platforms: -- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. +- Smart Contracts are generally developed with specific programming languages that can be interpreted by the underlying virtual-machine. These programming languages are often immature and inherently limited by the constraints of the virtual-machine. For example, the Ethereum Virtual Machine does not allow developers to implement automatic execution of code. Developers are also limited to the account-based system of the EVM, and they can only choose from a limited set of functions for their cryptographic operations. These are examples, but they hint at the lack of **flexibility** a smart contract environment often entails. - Smart Contracts are all run by the same virtual machine. This means that they compete for resources, which can severly restrain **performance**. And even if the state-machine were to be split in multiple subsets (e.g. via sharding), Smart Contracts would still need to be interpeted by a virtual machine, which would limit performance compared to a native application implemented at state-machine level (our benchmarks show an improvement on the order of x10 in performance when the virtual-machine is removed). -- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. +- Another issue with the fact that Smart Contracts share the same underlying environment is the resulting limitation in **sovereignty**. A decentralised application is an ecosystem that involves multiple players. If the application is built on a general-purpose virtual-machine blockchain, these players have very limited sovereignty over it, and are ultimately superseded by the governance of the underlying blockchain. If there is a bug in the application, very little can be done about it. Application-Specific Blockchains are designed to address these shortcomings. @@ -40,35 +40,36 @@ Application-Specific Blockchains are designed to address these shortcomings. Application-specific blockchains give maximum flexibility to developers: -- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. Lotion, Weave, ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). -- Developers can swap consensus engine. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. -- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. -- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). -- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. +- In Cosmos blockchains, the state-machine is typically connected to the underlying consensus engine via an interface called the [ABCI](https://tendermint.com/docs/spec/abci/). This interface can be wrapped in any programming language, meaning developers can build their state-machine in the programming language of their choice. +- Developers can choose among multiple frameworks to build their state-machine. The most widely used today is the Cosmos SDK, but others exist (e.g. [Lotion](https://github.com/nomic-io/lotion), [Weave](https://github.com/iov-one/weave), ...). The choice will most of the time be done based on the programming language they want to use (Cosmos SDK and Weave are in Golang, Lotion is in Javascript, ...). +- The ABCI also allows developers to swap the consensus engine of their application-specific blockchain. Today, only Tendermint is production-ready, but in the future other engines are expected to emerge. +- Even when they settle for a framework and consensus engine, developers still have the freedom to tweak them if they don't perfectly match their requirements in their pristine forms. +- Developers are free to explore the full spectrum of tradeoffs (e.g. number of validators vs transaction throughput, safety vs availability in asynchrony, ...) and design choices (DB or IAVL tree for storage, UTXO or account model, ...). +- Developers can implement automatic execution of code. In the Cosmos SDK, logic can be automatically triggered at the beginning and the end of each block. They are also free to choose the cryptographic library used in their application, as opposed to being constrained by what is made available by the underlying environment in the case of virtual-machine blockchains. -The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. +The list above contains a few examples that show how much flexibility application-specific blockchains give to developers. The goal of Cosmos and the Cosmos SDK is to make developer tooling as generic and composable as possible, so that each part of the stack can be forked, tweaked and improved without losing compatibility. As the community grows, more alternative for each of the core building blocks will emerge, giving more options to developers. ### Performance Decentralised applications built with Smart Contracts are inherently capped in performance by the underlying environment. For a decentralised application to optimise performance, it needs to be built as an application-specific blockchains. Here are the benefits of an application-specific blockchains with regards to performance: -- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. -- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation. -- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. +- Developers of application-specific blockchains can choose to operate with novel consensus engine such as Tendermint BFT. Compared to Proof-of-Work (used by most virtual-machine blockchains today), it offers significant gains in throuhgput. +- An application-specific blockchain only operates a single application, so that the application does not compete with others for computation and storage. This is the opposite of most non-sharded virtual-machine blockchains today, where smart contracts all compete for computation and storage. +- Even if a virtual-machine blockchain offered application-based sharding coupled with an efficient consensus algorithm, performance would still be limited by the virtual-machine itself. The real throughput bottleneck is the state-machine, and requiring transactions to be interpreted by a virtual-machine significantly increases the computational complexity of processing them. -### Security +### Security Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -- Developers can choose proven programming language like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. -- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. -- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. +- Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +- Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. +- Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. ### Sovereignty -One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. +One of the major benefits of application-specific blockchains is sovereignty. A decentralised application is an ecosystem that involves many actors: users, developers, third-party services, and more. When developers build on virtual-machine blockchain where many decentralised applications coexist, the community of the application is different than the community of the underlying blockchain, and the latter supersedes the former. If there is a bug or if a new feature is needed, the community of the application has very little sovereignty to upgrade the code. If the community of the underlying blockchain refuses to act, nothing can happen. -The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. +The fundamental issue here is that the governance of the application and the governance of the network are not aligned. This issue is solved by application-specific blockchains. Because application-specific blockchains specialize to operate a single application, the community of the application has full control over the entire chain. This ensures the community will not be stuck if a bug is discovered, and that it has the entire freedom to choose how it is going to evolve. ## Start Building Your Application-Specific Blockchain Today From 5b24d33068470b482bfeb661b6a52081092517cb Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:32:01 -0700 Subject: [PATCH 70/75] deleted some --- docs/basics/app-anatomy.md | 103 +++++++++------- docs/building-modules/modules-manager.md | 147 ----------------------- docs/concepts/encoding.md | 3 - docs/concepts/tx-msgs.md | 5 - 4 files changed, 58 insertions(+), 200 deletions(-) delete mode 100644 docs/building-modules/modules-manager.md delete mode 100644 docs/concepts/encoding.md delete mode 100644 docs/concepts/tx-msgs.md diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index dc58e389342a..15e1c9fc1e22 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -55,7 +55,7 @@ Blockchain Node | | Consensus | | The blockchain full-node presents itself as a binary, generally suffixed by `-d` for "daemon" (e.g. `appd` for `app` or `gaiad` for `gaia`). This binary is built by running a simple `main.go` function placed in `cmd/appd/`. This operation usually happens through the [Makefile](#dependencies-and-makefile). -To learn more about the `main.go` function, [click here](./node.md#main-function). +To learn more about the `main.go` function, [click here](../core/node.md#main-function). Once the main binary is built, the node can be started by running the `start` command. The core logic behind the `start` command is implemented in the SDK itself in the [`/server/start.go`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go) file. The main [`start` command function](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L31) takes a [`context`](https://godoc.org/github.com/cosmos/cosmos-sdk/client/context) and [`appCreator`](<#constructor-function-(`appCreator`)>) as arguments. The `appCreator` is a constructor function for the SDK application, and is used in the starting process of the full-node. @@ -73,11 +73,11 @@ In general, the core of the state-machine is defined in a file called `app.go`. The first thing defined in `app.go` is the `type` of the application. It is generally comprised of the following parts: -- **A reference to [`baseapp`](./baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. -- **A list of store keys**. The [store](./store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. -- **A list of module's `keepers`.** Each module defines an abstraction called `keeper`, which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. -- **A reference to a `codec`.** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). -- **A reference to a [module manager](./modules.md#module-manager)**. The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +- **A reference to [`baseapp`](../core/baseapp.md).** The custom application defined in `app.go` is an extension of the `baseapp` type. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://tendermint.com/docs/spec/abci/abci.html#overview) and the routing logic. When a transaction is relayed by Tendermint to the application, the latter uses `baseapp`'s methods to route them to the appropriate module. +- **A list of store keys**. The [store](../core/store.md), which contains the entire state, is implemented as a multistore (i.e. a store of stores) in the Cosmos SDK. Each module uses one or multiple stores in the multistore to persist their part of the state. These stores can be accessed with specific keys that are declared in the `app` type. These keys, along with the `keepers`, are at the heart of the [object-capabilities model](../intro/ocap.md) of the Cosmos SDK. +- **A list of module's `keepers`.** Each module defines an abstraction called [`keeper`](../building-modules/keeper.md), which handles reads and writes for this module's store(s). The `keeper`'s methods of one module can be called from other modules (if authorized), which is why they are declared in the application's type and exported as interfaces to other modules so that they are only allowed to access the authorized functions. +- **A reference to a [`codec`](../core/encoding.md).** The Cosmos SDK gives developers the freedom to choose the encoding framework for their application. The application's `codec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The `codec` must be deterministic. The default codec is [amino](./amino.md). +- **A reference to a [module manager](../building-modules/module-manager.md#manager)** and a [basic module manager](../building-modules/module-manager.md#basicmanager). The module manager is an object that contains a list of the application's module. It facilitates operations related to these modules, like registering [`routes`](./baseapp.md#routing), [query routes](#./baseapp.md#query-routing) or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). You can see an example of application type definition [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L73-L107). @@ -85,18 +85,19 @@ You can see an example of application type definition [here](https://github.com/ This function constructs a new application of the type defined above. It is called every time the full-node is started with the [`start`](https://github.com/cosmos/cosmos-sdk/blob/master/server/start.go#L117) command. Here are the main actions performed by this function: +- Instantiate a new [`codec`](../core/encoding.md) and initialize the `codec` of each of the application's module using the [basic manager](../building-modules/module-manager.md#basicmanager) - Instantiate a new application with a reference to a `baseapp` instance, a codec and all the appropriate store keys. -- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. -- Instantiate the application's [module manager](./module-manager.md) with the [`AppModule`](#application-module-interface) object of each of the application's modules. -- With the module manager, initialize the application's [`routes`](./baseapp.md#routing) and [query routes](./baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. -- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](./invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. -- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. +- Instantiate all the [`keeper`s](#keeper) defined in the application's `type` using the `NewKeeper` function of each of the application's modules. Note that `keepers` must be instantiated in the correct order, as the `NewKeeper` of one module might require a reference to another module's `keeper`. +- Instantiate the application's [module manager](../building-modules/module-manager.md#manager) with the [`AppModule`](#application-module-interface) object of each of the application's modules. +- With the module manager, initialize the application's [`routes`](../core/baseapp.md#routing) and [query routes](../core/baseapp.md#query-routing). When a transaction is relayed to the application by Tendermint via the ABCI, it is routed to the appropriate module's [`handler`](#handler) using the routes defined here. Likewise, when a query is received by the application, it is routed to the appropriate module's [`querier`](#querier) using the query routes defined here. +- With the module manager, register the [application's modules' invariants](./invariants.md). Invariants are variables (e.g. total supply of a token) that are evaluated at the end of each block. The process of checking invariants is done via a special module called the [`InvariantsRegistry`](../building-modules/invariants.md#invariant-registry). The value of the invariant should be equal to a predicted value defined in the module. Should the value be different than the predicted one, special logic defined in the invariant registry will be triggered (usually the chain is halted). This is useful to make sure no critical bug goes unnoticed and produces long-lasting effects that would be hard to fix. +- With the module manager, set the order of execution between the `InitGenesis`, `BegingBlocker` and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. - Set the remainer of application's parameters: - - [`InitChainer`](#initchainer): used to initialize the application when it is first started. - - [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - - [`anteHandler`](#baseapp.md#antehandler): used to handle fees and signature verification. -- Mount the stores. -- Return the application. + + [`InitChainer`](#initchainer): used to initialize the application when it is first started. + + [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). + + [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. +- Mount the stores. +- Return the application. Note that this function only creates an instance of the app, while the actual state is either carried over from the `~/.appd/data` folder if the node is restarted, or generated from the genesis file if the node is started for the first time. @@ -104,7 +105,7 @@ You can see an example of application constructor [here](https://github.com/cosm ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a [genesis file](./genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. +The `InitChainer` is a function that initializes the state of the application from a [genesis file](../core/genesis.md) (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the Tendermint engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its constructor via the [`SetInitChainer`](https://godoc.org/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the `InitGenesis` function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn will call the `InitGenesis` function of each of the modules it contains. Note that the order in which the modules' `InitGenesis` functions must be called has to be set in the module manager using the `SetOrderInitGenesis` method. This is done in the [application's constructor](#application-constructor), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. @@ -116,7 +117,7 @@ The SDK offers developers the possibility to implement automatic execution of co In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the `BeginBlock` and `EndBlock` functions of each of the application's modules. This is done by calling the `BeginBlock` and `EndBlock` functions of the module manager, which in turn will call the `BeginBLock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BegingBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlock` and `SetOrderEndBlock` methods respectively. This is done in the [application's constructor](#application-constructor), and the `SetOrderBeginBlock` and `SetOrderEndBlock` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. -As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as gas does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. +As a sidenote, it is important to remember that application-specific blockchains are deterministic. Developers must be careful not to introduce non-determinism in `BeginBlocker` or `EndBlocker`, and must also be careful not to make them too computationally expensive, as [gas](./accounts-fees-gas.md/gas) does not constrain the cost of `BeginBlocker` and `EndBlocker` execution. You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L224-L232). @@ -124,53 +125,55 @@ You can see an example of `BeginBlocker` and `EndBlocker` functions [here](https The `MakeCodec` function is the last important function of the `app.go` file. The goal of this function is to instantiate a codec `cdc` (e.g. amino) initialize the codec of the SDK and each of the application's modules using the `RegisterCodec` function. -To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a basic manager which lists all of the application's modules. It is instantiated in the `init()` function, and only serves to easily register non-dependent elements of application's modules (such as codec). To learn more about the basic module manager,. +To register the application's modules, the `MakeCodec` function calls `RegisterCodec` on `ModuleBasics`. `ModuleBasics` is a [basic manager](../building-modules/module-manager.md#basicmanager) which lists all of the application's modules. It is instanciated in the `init()` function, and only serves to easily register non-dependant elements of application's modules (such as codec). To learn more about the basic module manager, click [here](../building-modules/module-manager.md#basicmanager). You can see an example of a `MakeCodec` [here](https://github.com/cosmos/gaia/blob/master/app/app.go#L64-L70) ## Modules -Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by `baseapp` to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). +Modules are the heart and soul of an SDK application. They can be considered as state-machines within the state-machine. When a transaction is relayed from the underlying Tendermint engine via the ABCI to the application, it is routed by [`baseapp`](../core/baseapp.md) to the appropriate module in order to be processed. This paradigm enables developers to easily build complex state-machines, as most of the modules they need often already exist. For developers, most of the work involved in building an SDK application revolves around building custom modules required by their application that do not exist, and integrating them with modules that do already exist into one coherent application. In the application directory, the standard practice is to store modules in the `x/` folder (not to be confused with the SDK's `x/` folder, which contains already-built modules). + +To learn more about modules, [click here](./modules.md) ### Application Module Interface -Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57) and [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L44-L57). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. +Modules implement two interfaces defined in the Cosmos SDK, [`AppModuleBasic`](../building-modules/module-manager.md#appmodulebasic) and [`AppModule`](../building-modules/module-manager.md#appmodule). The former implements basic non-dependant elements of the module, such as the `codec`, while the latter handles the bulk of the module methods (including methods that require references to other modules' `keeper`s). Both the `AppModule` and `AppModuleBasic` types are defined in a file called `./module.go`. -`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. Important methods include: +`AppModule` exposes a collection of useful methods on the module that facilitates the composition of modules into a coherent application. These methods are are called from the `module manager`(../building-modules/module-manager.md#manager), which manages the application's collection of modules. -- `Route()` and `QueryRoute()`: These methods the name of the route and querier route for the module, for [messages](#message-types) to be routed to the module's [`handler`](#handler) and queries to be routes to the module's [`querier`](#querier). -- `NewHandler()` and `NewQuerierHandler()`: These methods return a `handler` and `querierHandler` respectively, in order to process a message or a query once they are routed. -- `BeginBlock()`, `EndBlock()` and `InitGenesis()`: These methods are executed respectively at the beginning of each block, at the end of each block and at the start of the chain. They implement special logic the module requires to be triggered during those events. For example, the `EndBlock` function is frequently used by modules where voting occurs to tally the result of the votes. -- `RegisterInvariants()`: This method registers the [invariants](./invariants.md) for the module. Invariants are checked at the end of every block to make sure no unpredicted behaviour is occuring. -- `AppModule`'s methods are called from the `module manager`, which manages the application's collection of modules. +To learn more about the application module interface, [click here](../building-modules/module-manager.md#application-module-interfaces). ### Message Types -A message is a custom type defined by each module that implements the [`message`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L8-L29) interface. Each `transaction` contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: +A message is a custom type defined by each module that implements the [`message`](../building-modules/messages-and-queries.md#messages) interface. Each [`transaction`](../core/transaction.md) contains one or multiple `messages`. When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://tendermint.com/docs/app-dev/abci-spec.html#delivertx). Then, the application handles the transaction: -1. Upon receiving the transaction, the application first unmarshals it from `[]bytes`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. -3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. -4. If the message is successfully processed, the state is updated. +1. Upon receiving the transaction, the application first unmarshalls it from `[]bytes`. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](#accounts-fees-gas.md) before extracting the message(s) contained in the transaction. +3. With the [`Type()`](https://github.com/cosmos/cosmos-sdk/blob/master/types/tx_msg.go#L16) method, `baseapp` is able to know which modules defines the message. It is then able to route it to the appropriate module's [handler](#handler) in order for the message to be processed. +4. If the message is successfully processed, the state is updated. For a more detailed look at a transaction lifecycle, click [here](./tx-lifecycle.md). Module developers create custom message types when they build their own module. The general practice is to prefix the type declaration of the message with `Msg`. For example, the message type [`MsgSend`](https://github.com/cosmos/cosmos-sdk/blob/master/x/bank/types/msgs.go#L10-L15) allows users to transfer tokens. It is processed by the handler of the `bank` module, which ultimately calls the `keeper` of the `auth` module in order to update the state. +To learn more about messages, [click here](../building-modules/messages-and-queries.md#messages). + ### Handler -The `handler` refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). +The [`handler`](../building-modules/handler.md) refers to the part of the module responsible for processing the message after it is routed by `baseapp`. `handler` functions of modules (except those of the `auth` module) are only executed if the transaction is relayed from Tendermint by the `DeliverTx` ABCI message. If the transaction is relayed by `CheckTx`, only stateless checks and fee-related (i.e. `auth` module-related) stateful checks are performed. To better understand the difference between `DeliverTx`and `CheckTx`, as well as the difference between stateful and stateless checks, click [here](./tx-lifecycle.md). The handler of a module is generally defined in a file called `handler.go` and consists of: -- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). -- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. +- A **switch function** `NewHandler` to route the message to the appropriate handler function. This function returns a `handler` function, and is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's router](../core/baseapp.md#routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/handler.go#L10-L22). +- **One handler function for each message type defined by the module**. Developers write the message processing logic in these functions. This generally involves doing stateful checks to ensure the message is valid and calling [`keeper`](#keeper)'s methods to update the state. Handler functions return a result of type [`sdk.Result`](https://github.com/cosmos/cosmos-sdk/blob/master/types/result.go#L14-L37), which informs the application on whether the message was successfully processed. +To learn more about handlers, [click here](../building-modules/handler.md). + ### Keeper -`Keepers` are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](./ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). +[`Keepers`](../building-module/keeper.md) are the gatekeepers of their module's store(s). To read or write in a module's store, it is mandatory to go through one of its `keeper`'s methods. This is ensured by the [object-capabilities](../core/ocap.md) model of the Cosmos SDK. Only objects that hold the key to a store can access it, and only the module's `keeper` should hold the key(s) to the module's store(s). `Keepers` are generally defined in a file called `keeper.go`. It contains the `keeper`'s type definition and methods. @@ -184,14 +187,18 @@ Along with the type definition, the next important component of the `keeper.go` The rest of the file defines the `keeper`'s methods, primarily getters and setters. You can check an example of a `keeper` implementation [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/keeper.go). -### Querier +To learn more about `keepers`, [click here](../building-modules/keeper.md). + +### Querier -`Queriers` are very similar to `handlers`, except they serve user queries to the state as opposed to processing transactions. A query is initiated from an [interface](#intefaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. +[`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](#interfaces) 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`](https://github.com/cosmos/cosmos-sdk/blob/master/baseapp/baseapp.go#L519-L556) method using `queryRoute`. The `Querier` of a module is defined in a file called `querier.go`, and consists of: -- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the application's query router. See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). -- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshaling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). +- A **switch function** `NewQuerier` to route the query to the appropriate `querier` function. This function returns a `querier` function, and is is registered in the [`AppModule`](#application-module-interface) to be used in the application's module manager to initialize the [application's query router](../core/baseapp.md#query-routing). See an example of such a switch [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L21-L34). +- - **One querier function for each data type defined by the module that needs to be queryable**. Developers write the query processing logic in these functions. This generally involves calling [`keeper`](#keeper)'s methods to query the state and marshalling it to JSON. See an example of `querier` functions [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/querier.go#L37-L101). + +To learn more about `queriers`, [click here](../building-modules/querier.md). ### Command-Line and REST Interfaces @@ -204,9 +211,11 @@ Generally, the commands related to a module are defined in a folder called `clie - Transactions commands let users generate new transactions so that they can be included in a block and eventually update the state. One command should be created for each [message type](#message-types) defined in the module. The command calls the constructor of the message with the parameters provided by the end-user, and wraps it into a transaction. The SDK handles signing and the addition of other transaction metadata. See examples of transactions commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/tx.go). - Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](./baseapp.md#query-routing), which routes them to the appropriate [querier](#querier) the `queryRoute` parameter supplied. See examples of query commands [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/cli/query.go). +To learn more about modules CLI, [click here](../building-modules/module-interfaces.md#cli). + #### REST -The module's REST interface lets users generate transactions and query the state through REST calls to the application's light client daemon (LCD). REST routes are defined in a file `client/rest/rest.go`, which is composed of: +The module's REST interface 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](https://github.com/cosmos/cosmos-sdk/blob/master/types/rest/rest.go#L32-L43) of the Cosmos SDK. @@ -214,19 +223,23 @@ The module's REST interface lets users generate transactions and query the state See an example of a module's `rest.go` file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/x/nameservice/client/rest/rest.go). +To learn more about modules REST interface, [click here](../building-modules/module-interfaces.md#rest). + ## Application Interface Interfaces let end-users interact with full-node clients. This means querying data from the full-node or creating and sending new transactions to be relayed by the full-node and eventually included in a block. -The main interface is the Command-Line Interface. The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: +The main interface is the [Command-Line Interface](../interfaces/cli.md). The CLI of an SDK application is built by aggregating [CLI commands](#cli) defined in each of the modules used by the application. The CLI of an application generally has the `-cli` suffix (e.g. `appcli`), and defined in a file called `cmd/appcli/main.go`. The file contains: - **A `main()` function**, which is executed to build the `appcli` interface client. This function prepares each command and adds them to the `rootCmd` before building them. At the root of `appCli`, the function adds generic commands like `status`, `keys` and `config`, query commands, tx commands and `rest-server`. -- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. -- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. -- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](./node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. +- **Query commands** are added by calling the `queryCmd` function, also defined in `appcli/main.go`. This function returns a Cobra command that contains the query commands defined in each of the application's modules (passed as an array of `sdk.ModuleClients` from the `main()` function), as well as some other lower level query commands such as block or validator queries. Query command are called by using the command `appcli query [query]` of the CLI. +- **Transaction commands** are added by calling the `txCmd` function. Similar to `queryCmd`, the function returns a Cobra command that contains the tx commands defined in each of the application's modules, as well as lower level tx commands like transaction signing or broadcasting. Tx commands are called by using the command `appcli tx [tx]` of the CLI. +- **A `registerRoutes` function**, which is called from the `main()` function when initializing the [application's light-client daemon (LCD)](../core/node.md#lcd) (i.e. `rest-server`). `registerRoutes` calls the `RegisterRoutes` function of each of the application's module, thereby registering the routes of the module to the lcd's router. The LCD can be started by running the following command `appcli rest-server`. See an example of an application's main command-line file [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/cmd/nscli/main.go). +To learn more about interfaces, [click here](../interfaces/intro.md). + ## Dependencies and Makefile This section is optional, as developers are free to choose their depencency manager and project building method. That said, the current most used framework for versioning control is [`go.mod`](https://github.com/golang/go/wiki/Modules). It ensures each of the libraries used throughout the application are imported with the correct version. An example can be found [here](https://github.com/cosmos/sdk-application-tutorial/blob/master/go.mod). diff --git a/docs/building-modules/modules-manager.md b/docs/building-modules/modules-manager.md deleted file mode 100644 index bfe4c9d2d297..000000000000 --- a/docs/building-modules/modules-manager.md +++ /dev/null @@ -1,147 +0,0 @@ -# Module Manager - -## Pre-requisite Reading - -- [Introduction to SDK Modules](./intro.md) - -## Synopsis - -Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../core/baseapp.md#routing), and allows the application developer to set the order of execution of a variety of functions like [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#begingblocker-and-endblocker). - -## Application Module Interfaces - -[Application module interfaces](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go) exist to facilitate the composition of modules together to form a functional SDK application. There are 3 main application module interfaces: - -- [`AppModuleBasic`](#appmodulebasic) for independent module functionalities. -- [`AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities). -- [`AppModuleGenesis`](#appmodulegenesis) for inter-dependent genesis-related module functionalities. - -The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/app-antomy.md#core-application-file). - -The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interract with other modules, typically through [`keeper`s](./keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application. - -Lastly the interface for genesis functionality `AppModuleGenesis` is separated out from full module functionality `AppModule` so that modules which -are only used for genesis can take advantage of the `Module` patterns without having to define many placeholder functions. - -### `AppModuleBasic` - -The [`AppModuleBasic`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L45-L57) interface defines the independent methods modules need to implement. - -```go -type AppModuleBasic interface { - Name() string - RegisterCodec(*codec.Codec) - - // genesis - DefaultGenesis() json.RawMessage - ValidateGenesis(json.RawMessage) error - - // client functionality - RegisterRESTRoutes(context.CLIContext, *mux.Router) - GetTxCmd(*codec.Codec) *cobra.Command - GetQueryCmd(*codec.Codec) *cobra.Command -} -``` - -Let us go through the methods: - -- `Name()`: Returns the name of the module as a `string`. -- `RegisterCodec(*codec.Codec)`: Registers the `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. -- `RegisterRESTRoutes(context.CLIContext, *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. -- `GetTxCmd(*codec.Codec)`: 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(*codec.Codec)`: Return the root [`query` command](./module-intefaces.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. - -All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager). - -### `AppModuleGenesis` - -The [`AppModuleGenesis`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L123-L127) interface is a simple embedding of the `AppModuleBasic` interface with two added methods. - -```go -type AppModuleGenesis interface { - AppModuleBasic - InitGenesis(sdk.Context, json.RawMessage) []abci.ValidatorUpdate - ExportGenesis(sdk.Context) json.RawMessage -} -``` - -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. - -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. - -### `AppModule` - -The [`AppModule`](https://github.com/cosmos/cosmos-sdk/blob/master/types/module/module.go#L130-L144) interface defines the inter-dependent methods modules need to implement. - -```go -type AppModule interface { - AppModuleGenesis - - // registers - RegisterInvariants(sdk.InvariantRegistry) - - // routes - Route() string - NewHandler() sdk.Handler - QuerierRoute() string - NewQuerierHandler() sdk.Querier - - BeginBlock(sdk.Context, abci.RequestBeginBlock) - EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate -} -``` - -`AppModule`s are managed by the [module manager](#manager). This interface embeds the `AppModuleGenesis` interface so that the manager can access all the independent and genesis inter-dependent methods of the module. This means that a concrete type implementing the `AppModule` interface must either implement all the methods of `AppModuleGenesis` (and by extension `AppModuleBasic`), or include a concrete type that does as parameter. - -Let us go through the methods of `AppModule`: - -- `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./invariants.md) of the module. If the invariants deviates from its predicted value, the [`InvariantRegistry`](./invariants.md#registry) triggers appropriate logic (most often the chain will be halted). -- `Route()`: Returns the name of the module's route, for [`message`s](./messages-and-queries.md#messages) to be routed to the module by [`baseapp`](../core/baseapp.md#message-routing). -- `NewHandler()`: Returns a [`handler`](./handler.md) given the `Type()` of the `message`, in order to process the `message`. -- `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`. -- `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. - -### Implementing the Application Module Interfaces - -Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). - -Almost every module need to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `NewHandler()` function often calls a `NewHandler(k keeper)` function defined in [`handler.go`](./handler.md) and therefore needs to pass the module's [`keeper`](./keeper.md) as parameter. - -```go -// example -type AppModule struct { - AppModuleBasic - keeper Keeper -} -``` - -In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type. - -If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so: - -```go -type AppModuleBasic struct{} -``` - -## Module Managers - -Module managers are used to manage collections of `AppModuleBasic` and `AppModule`. - -### `BasicManager` - -The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application: - -```go -type BasicManager map[string]AppModuleBasic -``` - - - -### `Manager` diff --git a/docs/concepts/encoding.md b/docs/concepts/encoding.md deleted file mode 100644 index 8113f63e9630..000000000000 --- a/docs/concepts/encoding.md +++ /dev/null @@ -1,3 +0,0 @@ -# Amnio Encoding - -TODO \ No newline at end of file diff --git a/docs/concepts/tx-msgs.md b/docs/concepts/tx-msgs.md deleted file mode 100644 index fde1963e3c2a..000000000000 --- a/docs/concepts/tx-msgs.md +++ /dev/null @@ -1,5 +0,0 @@ -# Transactions and Messages - -## Transactions - -## Messages From e96b1664dcf1d35c441f8ae6f41f01f62bbeb84b Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Wed, 21 Aug 2019 14:33:26 -0700 Subject: [PATCH 71/75] remove modules readme --- docs/building-modules/README.md | 78 --------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 docs/building-modules/README.md diff --git a/docs/building-modules/README.md b/docs/building-modules/README.md deleted file mode 100644 index 5b5743671751..000000000000 --- a/docs/building-modules/README.md +++ /dev/null @@ -1,78 +0,0 @@ -# Auth - -The `x/auth` modules is used for accounts - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/auth) - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/auth) - -# Bank - -The `x/bank` module is for transferring coins between accounts. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/bank). - -See the [specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/bank) - -# Stake - -The `x/staking` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/staking). - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/staking) - -# Slashing - -The `x/slashing` module is for Cosmos Delegated-Proof-of-Stake. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/slashing) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/slashing) - -# Distribution - -The `x/distribution` module is for distributing fees and inflation across bonded -stakeholders. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/distribution) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/distribution) - -# Governance - -The `x/gov` module is for bonded stakeholders to make proposals and vote on them. - -See the [API docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/gov) - -See the -[specification](https://github.com/cosmos/cosmos-sdk/tree/master/docs/spec/governance) - -To keep up with the current status of IBC, follow and contribute to [ICS](https://github.com/cosmos/ics) - -# Crisis - -The `x/crisis` module is for halting the blockchain under certain circumstances. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/crisis) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/crisis) - -# Mint - -The `x/mint` module is for flexible inflation rates and effect a balance between market liquidity and staked supply. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/mint) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/mint) - -# Params - -The `x/params` module provides a globally available parameter store. - -See the [API Docs](https://godoc.org/github.com/cosmos/cosmos-sdk/x/params) - -See the [specification](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/params) From 0444f02c8e5ce08821b559e7be349bb69874ed96 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 19:44:42 -0700 Subject: [PATCH 72/75] cli.md comments --- docs/interfaces/cli.md | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/docs/interfaces/cli.md b/docs/interfaces/cli.md index f1864a2593cb..ed15192968c5 100644 --- a/docs/interfaces/cli.md +++ b/docs/interfaces/cli.md @@ -6,7 +6,7 @@ ## Synopsis -This document describes how to create a commmand-line interface (CLI) for an application. A separate document for implementing a CLI for an SDK module can be found [here](#../building-modules/interfaces.md#cli). +This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/interfaces.md#cli). - [Application CLI Components](#application-cli-components) - [Commands](#commands) @@ -19,7 +19,7 @@ One of the main entrypoints of an application is the command-line interface. Thi ### Cobra -There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. +There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to. Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name: @@ -28,17 +28,17 @@ nscli tx nameservice buy-name --gas auto --gas-prices ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. +Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config ` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with. A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently. -Every flag has a name the user types to use the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: +### Creating Flags + +Every flag has a name the user types to include the flag. For example, the commonly used `--from` flag is declared as a constant in the SDK [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) file: ```go const FlagFrom = "from" ``` -The flag can be added to a command `cmd`, adding a default value and description: +The flag can be added to a command `cmd` right after the command is created, adding a default value and description: ```go cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign") ``` -The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. +The SDK client package includes a list of [flags](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go) that are commonly used across existing commands. Developers are free to create their own custom flags, following this format. ### Root Command Flags -It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: +It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is what that looks like: ```go rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint node") @@ -228,7 +232,7 @@ rootCmd.PersistentFlags().String(client.FlagChainID, "", "Chain ID of tendermint ### Transaction and Query Flags -To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. +To create a transaction, users enter a `tx` command and provide several flags. The SDK `./client/flags` package [`PostCommands()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L85-L116) function adds a set of basic flags to every transaction command. For queries, the [`GetCommand()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/flags/flags.go#L67-L82) function adds basic flags to query commands, such as the block `--height` to query from. For example, the following command creates a transaction to send 1000uatom from `sender-address` to `recipient-address`. The user is willing to pay 0.025uatom per unit gas but wants the transaction to be only generated offline (i.e. not broadcasted) and written, in JSON format, to the file `myUnsignedTx.json`. @@ -246,13 +250,13 @@ Here are the flags used: ## Configurations -The last function to define is, `initConfig`, which does exactly what it sounds like - initial configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: +The last function to define in `main.go` is `initConfig`, which does exactly what it sounds like - initialize configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following: 1. Read in the `config.toml` file. This same file is edited through `config` commands. 2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them. 3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc. -Here is an example of an `initConfig()` function from the nameservice tutorial CLI: +Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli): ```go func initConfig(cmd *cobra.Command) error { From 70fd35c5a380497f69ff7db00ce5af4d3e01cafe Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:05:43 -0700 Subject: [PATCH 73/75] comments --- docs/interfaces/query-lifecycle.md | 43 ++++++++---------------------- docs/interfaces/rest.md | 4 +-- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/docs/interfaces/query-lifecycle.md b/docs/interfaces/query-lifecycle.md index 6c69aa454e68..6c8a5b842620 100644 --- a/docs/interfaces/query-lifecycle.md +++ b/docs/interfaces/query-lifecycle.md @@ -60,7 +60,7 @@ The interactions from the users' perspective are a bit different, but the underl ### CLIContext -The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request. In particular, a `CLIContext` stores the following: +The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following: * **Codec**: The [encoder/decoder](,./core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object. * **Account Decoder**: The account decoder from the [`auth`](.../spec/auth) module, which translates `[]byte`s into accounts. @@ -76,11 +76,11 @@ The `CLIContext`'s primary role is to store data used during interactions with t ### Arguments and Route Creation -At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. +At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with. #### Parse Arguments -In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine node that has no inherent knowledge of the application types. Thus, the `CLIContext` `codec` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments (e.g. the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69)) have their own types that the application `codec` understands how to encode and decode. The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. +In this case, `Query` contains an [address](../core/accounts-fees.md) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address as the type [`QueryDelegatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L30-L38). All query arguments have their own types that the application `codec` understands how to encode and decode. For example, the [`staking`](https://github.com/cosmos/cosmos-sdk/blob/master/docs/spec/staking) module also has [`QueryValidatorParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L45-L53) and [`QueryBondsParams`](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/types/querier.go#L59-L69). The module [`querier`](.//building-modules/querier.md) declares these types and the application registers the `codec`s. Here is what the code looks like for the CLI command: @@ -104,7 +104,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/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"`. Here is what the code looks like: @@ -137,44 +137,23 @@ Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation ## Application Query Handling -[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 [querier](../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. 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 queriers [here](../building-modules/querier.md). + +Once a result is received from the querier, `baseapp` begins the process of returning a response to the user. ## Response -Since `Query()` is an ABCI function, Baseapp returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. +Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` [`verifyProof()`](https://github.com/cosmos/cosmos-sdk/blob/master/client/context/query.go#L136-L173) function before the response is returned. ### CLI Response -The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. - -Here is what the code looks like: - -```go -res, _, err := cliCtx.QueryWithData(route, bz) -var resp types.DelegationResponses -if err := cdc.UnmarshalJSON(res, &resp); err != nil { - return err -} -return cliCtx.PrintOutput(resp) -``` +The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/cli/query.go#L252-L293). ### REST Response -The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. - -Here is what the code looks like: - -```go -res, height, err := cliCtx.QueryWithData(endpoint, bz) -if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return -} -cliCtx = cliCtx.WithHeight(height) -rest.PostProcessResponse(w, cliCtx, res) -``` +The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error. To see the code, click [here](https://github.com/cosmos/cosmos-sdk/blob/master/x/staking/client/rest/utils.go#L115-L148). ## Next diff --git a/docs/interfaces/rest.md b/docs/interfaces/rest.md index bf4a010d0fa8..2b0e3ba2b633 100644 --- a/docs/interfaces/rest.md +++ b/docs/interfaces/rest.md @@ -7,7 +7,7 @@ ## Synopsis -This document describes how to create a REST interface for an SDK application. A separate document for creating a module REST interface can be found [here](#../module-interfaces.md#rest). +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). - [Application REST Interface](#application-rest-interface) - [REST Server](#rest-server) @@ -42,7 +42,7 @@ Of the five, the only attribute that developers will need to configure is the ro ## 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 `RegisterRoutes()` function 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.md#rest) function, application developers simply use the Module Manager to call this function for each module. +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 `RegisterRoutes()` function 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.md/module-interfaces.md#rest) function, application developers simply use the Module Manager to call this function for each module. 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: From ee08a01e42ed0ce89a4aef5af91a3a3973754441 Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 27 Aug 2019 20:15:45 -0700 Subject: [PATCH 74/75] module-interfaces comments --- docs/building-modules/module-interfaces.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index f1136e63d72c..300bd6b0817c 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -18,11 +18,11 @@ This document details how to build CLI and REST interfaces for a module. Example ## CLI -One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md) and [**queries**](./messages-and-queries.md). The CLI files are typically found in the `./x/moduleName/client/cli` folder. +One of the main interfaces for an application is the [command-line interface](../interfaces/cli.md). This entrypoint created by the application developer will add commands from the application's modules to let end-users create [**messages**](./messages-and-queries.md#messages) and [**queries**](./messages-and-queries.md#queries). The CLI files are typically found in the `./x/moduleName/client/cli` folder. ### 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. Here is an example from the nameservice tutorial: +[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. Here is an example from the [nameservice tutorial](https://cosmos.network/docs/tutorial/cli.html#transactions): ```go func GetCmdBuyName(cdc *codec.Codec) *cobra.Command { @@ -74,9 +74,6 @@ This getter function creates the command for the Buy Name transaction. It does t + 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. - -#### GetTxCmd - 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`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) `GetTxCmd()` function, which adds the `Sign` and `MultiSign` commands. An application using this module likely adds `auth` module commands to its root `TxCmd` command by calling `txCmd.AddCommand(authModuleClient.GetTxCmd())`. ```go @@ -98,7 +95,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { ### Query Commands -[Queries](./messages-and-queries.md) 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 and have the prefix `GetCmdQuery`. Here is an example of a query command from the [nameservice module CLI](https://cosmos.network/docs/tutorial/cli.html#queries): ```go func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command { @@ -137,9 +134,8 @@ This query returns the address that owns a particular name. The getter function + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command. -#### GetQueryCmd -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`](#gettxcmd) 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. ### Flags @@ -167,11 +163,13 @@ Since `PostCommands()` includes all of the basic flags required for a transactio ## REST -Applications are typically required to support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. +Applications typically support web services that use HTTP requests (e.g. a web wallet like [Lunie.io](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. + +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. ### Request Types -Request types must be defined for all *transaction* requests. 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. +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](https://cosmos.network/docs/tutorial/rest.html) module: From 6914e0da10f3800895dcfcb2539914b6f0d1646a Mon Sep 17 00:00:00 2001 From: Gloria Zhao Date: Tue, 17 Sep 2019 12:00:48 -0700 Subject: [PATCH 75/75] last comment --- docs/building-modules/module-interfaces.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/building-modules/module-interfaces.md b/docs/building-modules/module-interfaces.md index 300bd6b0817c..ef4ea1273bc2 100644 --- a/docs/building-modules/module-interfaces.md +++ b/docs/building-modules/module-interfaces.md @@ -129,8 +129,8 @@ This query returns the address that owns a particular name. The getter function - **`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 [`CLIContext`](./query-lifecycle.md#clicontext) with the application `codec`. + If applicable, the `CLIContext` 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 `CLIContext` parameters in this case because the query does not involve any information about the user. - + The `queryRoute` is used to construct a route Baseapp will use to route the query to the appropriate [querier](./querier.md). Module queries are `custom` type queries (some SDK modules have exceptions, such as `auth` and `gov` module queries). - + The `CLIContext` query function relays the query to a node and retrieves the response. + + The `queryRoute` is used to construct a `path` [`baseapp`](../basics/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`](../basics/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 `CLIContext` `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. In addition, it will verify the returned proof if `TrustNode` is disabled. If proof verification fails or the query height is invalid, an error will be returned. + The `codec` is used to nmarshal the response and the `CLIContext` is used to print the output back to the user. - **Flags.** Add any [flags](#flags) to the command.