From 38a36ce57f1bc1e1094628455eca01a7164fc1d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juli=C3=A1n=20Toledano?= Date: Wed, 9 Oct 2024 21:18:36 +0200 Subject: [PATCH] docs: update learn/beginner docs (#22191) (cherry picked from commit fc9ca8ea2021867480a69db66398638dd0e947c4) --- docs/learn/beginner/00-app-anatomy.md | 30 +++++------ docs/learn/beginner/01-tx-lifecycle.md | 14 ++--- docs/learn/beginner/02-query-lifecycle.md | 18 ++++--- docs/learn/beginner/03-accounts.md | 66 +++++++++++------------ docs/learn/beginner/04-gas-fees.md | 12 ++--- 5 files changed, 71 insertions(+), 69 deletions(-) diff --git a/docs/learn/beginner/00-app-anatomy.md b/docs/learn/beginner/00-app-anatomy.md index 9b0191949522..8aff2f10c47a 100644 --- a/docs/learn/beginner/00-app-anatomy.md +++ b/docs/learn/beginner/00-app-anatomy.md @@ -59,17 +59,17 @@ 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`](../advanced/00-baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by CometBFT to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://docs.cometbft.com/v1.0/spec/abci/) and the [routing logic](../advanced/00-baseapp.md#routing). +* **A reference to [`baseapp`](../advanced/00-baseapp.md).** The custom application defined in `app.go` is an extension of `baseapp`. When a transaction is relayed by CometBFT to the application, `app` uses `baseapp`'s methods to route them to the appropriate module. `baseapp` implements most of the core logic for the application, including all the [ABCI methods](https://docs.cometbft.com/v1.0/spec/abci/) and the [routing logic](../advanced/00-baseapp.md#service-routers). * **A list of store keys**. The [store](../advanced/04-store.md), which contains the entire state, is implemented as a [`multistore`](../advanced/04-store.md#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](../advanced/10-ocap.md) of the Cosmos SDK. * **A list of module's `keeper`s.** Each module defines an abstraction called [`keeper`](../../build/building-modules/06-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 the latter can only access the authorized functions. * **A reference to an [`appCodec`](../advanced/05-encoding.md).** The application's `appCodec` is used to serialize and deserialize data structures in order to store them, as stores can only persist `[]bytes`. The default codec is [Protocol Buffers](../advanced/05-encoding.md). * **A reference to a [`legacyAmino`](../advanced/05-encoding.md) codec.** Some parts of the Cosmos SDK have not been migrated to use the `appCodec` above, and are still hardcoded to use Amino. Other parts explicitly use Amino for backwards compatibility. For these reasons, the application still holds a reference to the legacy Amino codec. Please note that the Amino codec will be removed from the SDK in the upcoming releases. -* **A reference to a [module manager](../../build/building-modules/01-module-manager.md#manager)**. The module manager is an object that contains a list of the application's modules. It facilitates operations related to these modules, like registering their [`Msg` service](../advanced/00-baseapp.md#msg-services) and [gRPC `Query` service](../advanced/00-baseapp.md#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`PreBlocker`](#preblocker) and [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). +* **A reference to a [module manager](../../build/building-modules/01-module-manager.md#manager)**. The module manager is an object that contains a list of the application's modules. It facilitates operations related to these modules, like registering their [`Msg` service](../../build/building-modules/03-msg-services.md) and [gRPC `Query` service](#grpc-query-services), or setting the order of execution between modules for various functions like [`InitChainer`](#initchainer), [`PreBlocker`](#preblocker) and [`BeginBlocker` and `EndBlocker`](#beginblocker-and-endblocker). See an example of application type definition from `simapp`, the Cosmos SDK's own app used for demo and testing purposes: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L173-L212 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/simapp/app.go#L145-L186 ``` ### Constructor Function @@ -77,7 +77,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L173-L21 Also defined in `app.go` is the constructor function, which constructs a new application of the type defined in the preceding section. The function must fulfill the `AppCreator` signature in order to be used in the [`start` command](../advanced/03-node.md#start-command) of the application's daemon command. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/server/types/app.go#L66-L68 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/server/types/app.go#L66-L68 ``` Here are the main actions performed by this function: @@ -86,7 +86,7 @@ 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`](#keeper) objects 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](../../build/building-modules/01-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 [`Msg` services](../advanced/00-baseapp.md#msg-services), [gRPC `Query` services](../advanced/00-baseapp.md#grpc-query-services), [legacy `Msg` routes](../advanced/00-baseapp.md#routing), and [legacy query routes](../advanced/00-baseapp.md#query-routing). When a transaction is relayed to the application by CometBFT via the ABCI, it is routed to the appropriate module's [`Msg` service](#msg-services) using the routes defined here. Likewise, when a gRPC query request is received by the application, it is routed to the appropriate module's [`gRPC query service`](#grpc-query-services) using the gRPC routes defined here. The Cosmos SDK still supports legacy `Msg`s and legacy CometBFT queries, which are routed using the legacy `Msg` routes and the legacy query routes, respectively. +* With the module manager, initialize the application's [`Msg` services](../../build/building-modules/03-msg-services.md), [gRPC `Query` services](#grpc-query-services), [legacy `Msg` routes](../advanced/00-baseapp.md#routing), and [legacy query routes](../advanced/00-baseapp.md#query-routing). When a transaction is relayed to the application by CometBFT via the ABCI, it is routed to the appropriate module's [`Msg` service](#msg-services) using the routes defined here. Likewise, when a gRPC query request is received by the application, it is routed to the appropriate module's [`gRPC query service`](#grpc-query-services) using the gRPC routes defined here. The Cosmos SDK still supports legacy `Msg`s and legacy CometBFT queries, which are routed using the legacy `Msg` routes and the legacy query routes, respectively. * With the module manager, set the order of execution between the `InitGenesis`, `PreBlocker`, `BeginBlocker`, and `EndBlocker` functions of each of the [application's modules](#application-module-interface). Note that not all modules implement these functions. * Set the remaining application parameters: * [`InitChainer`](#initchainer): used to initialize the application when it is first started. @@ -101,19 +101,19 @@ Note that the constructor function only creates an instance of the app, while th See an example of application constructor from `simapp`: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L223-L575 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/app.go#L199-L643 ``` ### InitChainer -The `InitChainer` is a function that initializes the state of the application from a genesis file (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the CometBFT engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its [constructor](#constructor-function) via the [`SetInitChainer`](https://pkg.go.dev/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 (i.e. token balances of genesis accounts). It is called when the application receives the `InitChain` message from the CometBFT engine, which happens when the node is started at `appBlockHeight == 0` (i.e. on genesis). The application must set the `InitChainer` in its [constructor](#constructor-function) via the [`SetInitChainer`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.52.0-beta.1/baseapp#BaseApp.SetInitChainer) method. In general, the `InitChainer` is mostly composed of the [`InitGenesis`](../../build/building-modules/08-genesis.md#initgenesis) function of each of the application's modules. This is done by calling the `InitGenesis` function of the module manager, which in turn calls 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 [module manager's](../../build/building-modules/01-module-manager.md) `SetOrderInitGenesis` method. This is done in the [application's constructor](#constructor-function), and the `SetOrderInitGenesis` has to be called before the `SetInitChainer`. See an example of an `InitChainer` from `simapp`: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L626-L634 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/app.go#L714-L726 ``` ### PreBlocker @@ -133,7 +133,7 @@ The new ctx must be passed to all the other lifecycle methods. ### BeginBlocker and EndBlocker -The Cosmos SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two functions called `BeginBlocker` and `EndBlocker`. They are called when the application receives the `FinalizeBlock` messages from the CometBFT consensus engine, which happens respectively at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its [constructor](#constructor-function) via the [`SetBeginBlocker`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/baseapp#BaseApp.SetEndBlocker) methods. +The Cosmos SDK offers developers the possibility to implement automatic execution of code as part of their application. This is implemented through two functions called `BeginBlocker` and `EndBlocker`. They are called when the application receives the `FinalizeBlock` messages from the CometBFT consensus engine, which happens respectively at the beginning and at the end of each block. The application must set the `BeginBlocker` and `EndBlocker` in its [constructor](#constructor-function) via the [`SetBeginBlocker`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.52.0-beta.1/baseapp#BaseApp.SetBeginBlocker) and [`SetEndBlocker`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.52.0-beta.1/baseapp#BaseApp.SetEndBlocker) methods. In general, the `BeginBlocker` and `EndBlocker` functions are mostly composed of the [`BeginBlock` and `EndBlock`](../../build/building-modules/06-preblock-beginblock-endblock.md) 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 calls the `BeginBlock` and `EndBlock` functions of each of the modules it contains. Note that the order in which the modules' `BeginBlock` and `EndBlock` functions must be called has to be set in the module manager using the `SetOrderBeginBlockers` and `SetOrderEndBlockers` methods, respectively. This is done via the [module manager](../../build/building-modules/01-module-manager.md) in the [application's constructor](#constructor-function), and the `SetOrderBeginBlockers` and `SetOrderEndBlockers` methods have to be called before the `SetBeginBlocker` and `SetEndBlocker` functions. @@ -142,15 +142,15 @@ As a sidenote, it is important to remember that application-specific blockchains See an example of `BeginBlocker` and `EndBlocker` functions from `simapp` ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L613-L620 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/app.go#L700-L708 ``` ### Register Codec -The `EncodingConfig` structure is the last important part of the `app.go` file. The goal of this structure is to define the codecs that will be used throughout the app. +The `EncodingConfig` structure is the last important part of the `app.go` file. This structure's purpose is to define the codecs that will be used throughout the app. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/params/encoding.go#L9-L16 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/params/encoding.go#L9-L16 ``` Here are descriptions of what each of the four fields means: @@ -166,7 +166,7 @@ An application should create its own encoding config. See an example of a `simappparams.EncodingConfig` from `simapp`: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/params/encoding.go#L11-L16 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/simapp/params/encoding.go#L9-L16 ``` ## Modules @@ -197,7 +197,7 @@ For more details, see [transaction lifecycle](./01-tx-lifecycle.md). Module developers create custom `Msg` services when they build their own module. The general practice is to define the `Msg` Protobuf service in a `tx.proto` file. For example, the `x/bank` module defines a service with two methods to transfer tokens: ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/bank/v1beta1/tx.proto#L13-L36 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/bank/proto/cosmos/bank/v1beta1/tx.proto#L13-L41 ``` Service methods use `keeper` in order to update the module state. @@ -237,7 +237,7 @@ Each module defines command-line commands, gRPC services, and REST routes to be Generally, the [commands related to a module](../../build/building-modules/09-module-interfaces.md#cli) are defined in a folder called `client/cli` in the module's folder. The CLI divides commands into two categories, 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](#msg-services) 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 Cosmos SDK handles signing and the addition of other transaction metadata. -* Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../advanced/00-baseapp.md#query-routing), which routes them to the appropriate [querier](#grpc-query-services) the `queryRoute` parameter supplied. +* Queries let users query the subset of the state defined by the module. Query commands forward queries to the [application's query router](../advanced/00-baseapp.md#grpc-query-router), which routes them to the appropriate [querier](#grpc-query-services) the `queryRoute` parameter supplied. #### gRPC diff --git a/docs/learn/beginner/01-tx-lifecycle.md b/docs/learn/beginner/01-tx-lifecycle.md index 4888baa60a61..f329e74f7c79 100644 --- a/docs/learn/beginner/01-tx-lifecycle.md +++ b/docs/learn/beginner/01-tx-lifecycle.md @@ -33,7 +33,7 @@ Additionally, there are several [flags](../advanced/07-cli.md) users can use to * `--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 to 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. -* `--timeout-height` specifies a block timeout height to prevent the tx from being committed past a certain height. +* `--timeout-timestamp` specifies a block timeout timestamp to prevent the tx from being committed past a certain time. The ultimate value of the fees paid is equal to the gas multiplied by the gas prices. In other words, `fees = ceil(gas * gasPrices)`. Thus, since fees can be calculated using gas prices and vice versa, the users specify only one of the two. @@ -49,7 +49,7 @@ appd tx send 1000uatom --from --gas auto --ga ### Other Transaction Creation Methods -The command-line is an easy way to interact with an application, but `Tx` can also be created using a [gRPC or REST interface](../advanced/06-grpc_rest.md) or some other entry point defined by the application developer. From the user's perspective, the interaction depends on the web interface or wallet they are using (e.g. creating `Tx` using [Keplr](https://www.keplr.app/) and signing it with a Ledger Nano S). +The command-line is an easy way to interact with an application, but `Tx` can also be created using a [gRPC or REST interface](../advanced/06-grpc_rest.md) or some other entry point defined by the application developer. From the user's perspective, the interaction depends on the web interface or wallet they are using (e.g. creating `Tx` using [Keplr](https://www.keplr.app/) and signing it with any [Ledger device](https://www.ledger.com/)). ## Transaction Broadcasting @@ -108,7 +108,7 @@ Let's say there is a transaction that involves transferring tokens. The message ### Validation -Preliminary checks are performed. These include signature verification to ensure the transaction hasn't been tampered with and checking if the transaction meets the minimum fee requirements, which is handled by the `AnteHandler`. The `Antehandler` is invoked during the `runTx` method in `BaseApp`. +Preliminary checks are performed. These include signature verification to ensure the transaction hasn't been tampered with and checking if the transaction meets the minimum fee requirements, which is handled by the `AnteHandler`. The `AnteHandler` is invoked during the `runTx` method in `BaseApp`. #### Types of Transaction Checks @@ -133,11 +133,11 @@ Full-nodes use these checks during the validation process to quickly reject inva #### ValidateBasic (deprecated) * Messages ([`sdk.Msg`](../advanced/01-transactions.md#messages)) are extracted from transactions (`Tx`). The `ValidateBasic` method of the `sdk.Msg` interface implemented by the module developer is run for each transaction. -* To discard obviously invalid messages, the `BaseApp` type calls the `ValidateBasic` method very early in the processing of the message in the [`CheckTx`](../advanced/00-baseapp.md#checktx) and [`DeliverTx`](../advanced/00-baseapp.md#delivertx) transactions. +* To discard obviously invalid messages, the `BaseApp` type calls the `ValidateBasic` method very early in the processing of the message in the [`CheckTx`](../advanced/00-baseapp.md#checktx) and `DeliverTx` transactions. `ValidateBasic` can include only **stateless** checks (the checks that do not require access to the state). :::warning -The `ValidateBasic` method on messages has been deprecated in favor of validating messages directly in their respective [`Msg` services](../../build/building-modules/03-msg-services.md#Validation). +The `ValidateBasic` method on messages has been deprecated in favor of validating messages directly in their respective [`Msg` services](../../build/building-modules/03-msg-services.md#validation). Read [RFC 001](https://docs.cosmos.network/main/rfc/rfc-001-tx-validation) for more details. ::: @@ -162,9 +162,9 @@ After the transaction has been appropriately routed to the correct module by the For messages that adhere to older standards or specific formats, a routing function retrieves the route name from the message, identifying the corresponding module. The message is then processed by the designated handler within that module, ensuring accurate and consistent application of the transaction's logic. -4. During the execution, the module's handler will modify the state as required by the business logic. This could involve writing to the module's portion of the state store. +1. During the execution, the module's handler will modify the state as required by the business logic. This could involve writing to the module's portion of the state store. -5. Modules can emit events and log information during execution, which are used for monitoring and querying transaction outcomes. +2. Modules can emit events and log information during execution, which are used for monitoring and querying transaction outcomes. During the module execution phase, each message that has been routed to the appropriate module is processed according to the module-specific business logic. For example, the `handleMsgSend` function in the bank module processes `MsgSend` messages by checking balances, transferring tokens, and emitting events: diff --git a/docs/learn/beginner/02-query-lifecycle.md b/docs/learn/beginner/02-query-lifecycle.md index bdaa51766993..a83bbe112a47 100644 --- a/docs/learn/beginner/02-query-lifecycle.md +++ b/docs/learn/beginner/02-query-lifecycle.md @@ -83,14 +83,14 @@ The first thing that is created in the execution of a CLI command is a `client.C The `client.Context` 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. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/context.go#L25-L68 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/client/context.go#L29-L86 ``` The `client.Context`'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 `MyQuery`, the `client.Context` 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 `client.Context`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `client.Context` contains a `Writer` to write output when the response is returned. These steps are further described in later sections. ### Arguments and Route Creation -At this point in the lifecycle, the user has created a CLI command with all of the data they wish to include in their query. A `client.Context` exists to assist in the rest of the `MyQuery`'s journey. Now, the next step is to parse the command or request, extract the arguments, and encode everything. These steps all happen on the user side within the interface they are interacting with. +At this point in the lifecycle, the user has created a CLI command with all of the data they wish to include in their query. A `client.Context` exists to assist in the rest of the `MyQuery`'s journey. Now, the next steps are to parse the command or request, extract the arguments, and encode everything. These steps all happen on the user side within the interface they are interacting with. #### Encoding @@ -99,23 +99,25 @@ In our case (querying an address's delegations), `MyQuery` contains an [address] Here is what the code looks like for the CLI command: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/client/cli/query.go#L315-L318 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/client/grpc_query.go#L64-L68 ``` #### gRPC Query Client Creation -The Cosmos SDK leverages code generated from Protobuf services to make queries. The `staking` module's `MyQuery` service generates a `queryClient`, which the CLI uses to make queries. Here is the relevant code: +The Cosmos SDK uses Protobuf-generated services for queries. The `staking` module's `MyQuery` service generates a `queryClient` used by the CLI. + +With the introduction of AutoCLI, query client creation is now automated and integrated into the module's setup. This approach simplifies the process of exposing module queries through the CLI. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/client/cli/query.go#L308-L343 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/staking/autocli.go#L73-L81 ``` -Under the hood, the `client.Context` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query fully-qualified service method name as path (in our case: `/cosmos.staking.v1beta1.Query/Delegations`), and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../advanced/03-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 `client.Context` still contains a `Query()` function to retrieve the pre-configured node and relay queries. It takes the fully-qualified service method name as a path (e.g. `/cosmos.staking.v1beta1.Query/Delegations`) and arguments as parameters. The function retrieves the RPC Client, creates `ABCIQueryOptions`, and makes the ABCI call using `ABCIQueryWithOptions()`. Here is what the code looks like: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/query.go#L79-L113 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/client/query.go#L64-L98 ``` ## RPC @@ -141,7 +143,7 @@ Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci The application [`codec`](../advanced/05-encoding.md) is used to unmarshal the response to a JSON and the `client.Context` prints the output to the command line, applying any configurations such as the output type (text, JSON or YAML). ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/context.go#L341-L349 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/client/context.go#L391-L398 ``` And that's a wrap! The result of the query is outputted to the console by the CLI. diff --git a/docs/learn/beginner/03-accounts.md b/docs/learn/beginner/03-accounts.md index b9f7eefa6016..99c9b30267f8 100644 --- a/docs/learn/beginner/03-accounts.md +++ b/docs/learn/beginner/03-accounts.md @@ -5,7 +5,7 @@ sidebar_position: 1 # Accounts :::note Synopsis -This document describes the in-built account and public key system of the Cosmos SDK. +This document describes the built-in account and public key system of the Cosmos SDK. ::: :::note Pre-requisite Readings @@ -17,7 +17,7 @@ This document describes the in-built account and public key system of the Cosmos ## Account Definition -In the Cosmos SDK, an _account_ designates a pair of _public key_ `PubKey` and _private key_ `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../../build/building-modules/02-messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#keys-accounts-addresses-and-signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`. +In the Cosmos SDK, an _account_ designates a pair of _public key_ `PubKey` and _private key_ `PrivKey`. The `PubKey` can be used to derive different types of `Addresses` (such as account addresses, validator addresses, and consensus addresses), with one unique address generated for each type. These `Addresses` are used to identify various actors in the application. `Addresses` are also associated with [`message`s](../../build/building-modules/02-messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#keys-accounts-addresses-and-signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`. For HD key derivation the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). The BIP32 allows users to create an HD wallet (as specified in [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)) - a set of accounts derived from an initial secret seed. A seed is usually created from a 12- or 24-word mnemonic. A single seed can derive any number of `PrivKey`s using a one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved. @@ -48,9 +48,9 @@ In the node, all data is stored using Protocol Buffers serialization. The Cosmos SDK supports the following digital key schemes for creating digital signatures: -* `secp256k1`, as implemented in the [Cosmos SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keys/secp256k1/secp256k1.go). -* `secp256r1`, as implemented in the [Cosmos SDK's `crypto/keys/secp256r1` package](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keys/secp256r1/pubkey.go), -* `tm-ed25519`, as implemented in the [Cosmos SDK `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keys/ed25519/ed25519.go). This scheme is supported only for the consensus validation. +* `secp256k1`, as implemented in the [Cosmos SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keys/secp256k1/secp256k1.go). +* `secp256r1`, as implemented in the [Cosmos SDK's `crypto/keys/secp256r1` package](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keys/secp256r1/pubkey.go), +* `tm-ed25519`, as implemented in the [Cosmos SDK `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keys/ed25519/ed25519.go). This scheme is supported only for the consensus validation. | | Address length in bytes | Public key length in bytes | Used for transaction authentication | Used for consensus (cometbft) | | :----------: | :---------------------: | :------------------------: | :---------------------------------: | :-----------------------------: | @@ -62,7 +62,7 @@ The Cosmos SDK supports the following digital key schemes for creating digital s `Addresses` and `PubKey`s are both public information that identifies actors in the application. `Account` is used to store authentication information. The basic account implementation is provided by a `BaseAccount` object. -Each account is identified using `Address` which is a sequence of bytes derived from a public key. In the Cosmos SDK, we define 3 types of addresses that specify a context where an account is used: +Each account is identified using an `Address` which is a sequence of bytes derived from a public key. In the Cosmos SDK, we define 3 types of addresses that specify a context where an account is used: * `AccAddress` identifies users (the sender of a `message`). * `ValAddress` identifies validator operators. @@ -71,7 +71,7 @@ Each account is identified using `Address` which is a sequence of bytes derived These types implement the `Address` interface: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/address.go#L126-L134 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/address.go#L145-L155 ``` Address construction algorithm is defined in [ADR-28](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-028-public-key-addresses.md). @@ -83,10 +83,10 @@ sdk.AccAddress(pub.Address().Bytes()) Of note, the `Marshal()` and `Bytes()` method both return the same raw `[]byte` form of the address. `Marshal()` is required for Protobuf compatibility. -For user interaction, addresses are formatted using [Bech32](https://en.bitcoin.it/wiki/Bech32) and implemented by the `String` method. The Bech32 method is the only supported format to use when interacting with a blockchain. The Bech32 human-readable part (Bech32 prefix) is used to denote an address type. Example: +For user interaction, addresses are formatted using [Bech32](https://en.bitcoin.it/wiki/Bech32). This formatting is handled by an address codec. The Bech32 format is the only supported format for interacting with a blockchain. The Bech32 human-readable part (Bech32 prefix) is used to denote an address type. The address codec is responsible for encoding and decoding addresses between their binary representation and the Bech32 string format. Here's an example of how the address codec formats addresses: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/address.go#L299-L316 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/codec/address/bech32_codec.go#L95-L111 ``` | | Address Bech32 Prefix | @@ -97,10 +97,10 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/address.go#L299- ### Public Keys -Public keys in Cosmos SDK are defined by `cryptotypes.PubKey` interface. Since public keys are saved in a store, `cryptotypes.PubKey` extends the `proto.Message` interface: +Public keys in Cosmos SDK are defined by `cryptotypes.PubKey` interface. Since public keys are saved in a store, the `cryptotypes.PubKey` extends the `proto.Message` interface: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/types/types.go#L8-L17 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/types/types.go#L8-L17 ``` A compressed format is used for `secp256k1` and `secp256r1` serialization. @@ -110,11 +110,11 @@ A compressed format is used for `secp256k1` and `secp256r1` serialization. This prefix is followed by the `x`-coordinate. -Public Keys are not used to reference accounts (or users) and in general are not used when composing transaction messages (with few exceptions: `MsgCreateValidator`, `Validator` and `Multisig` messages). -For user interactions, `PubKey` is formatted using Protobufs JSON ([ProtoMarshalJSON](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/codec/json.go#L14-L34) function). Example: +Public Keys are not used to reference accounts (or users) and in general are not used when composing transaction messages (with a few exceptions: `MsgCreateValidator`, `Validator` and `Multisig` messages). +For user interactions, `PubKey` is formatted using Protobufs JSON ([ProtoMarshalJSON](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/codec/json.go#L14-L34) function). Example: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/keys/output.go#L23-L39 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/client/keys/output.go#L24-L47 ``` ## Keyring @@ -122,7 +122,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/keys/output.go# A `Keyring` is an object that stores and manages accounts. In the Cosmos SDK, a `Keyring` implementation follows the `Keyring` interface: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keyring/keyring.go#L57-L105 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keyring/keyring.go#L57-L109 ``` The default implementation of `Keyring` comes from the third-party [`99designs/keyring`](https://github.com/99designs/keyring) library. @@ -132,34 +132,34 @@ A few notes on the `Keyring` methods: * `Sign(uid string, msg []byte) ([]byte, types.PubKey, error)` strictly deals with the signature of the `msg` bytes. You must prepare and encode the transaction into a canonical `[]byte` form. Because protobuf is not deterministic, it has been decided in [ADR-020](../../architecture/adr-020-protobuf-transaction-encoding.md) that the canonical `payload` to sign is the `SignDoc` struct, deterministically encoded using [ADR-027](../../architecture/adr-027-deterministic-protobuf-serialization.md). Note that signature verification is not implemented in the Cosmos SDK by default, it is deferred to the [`anteHandler`](../advanced/00-baseapp.md#antehandler). ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/tx/v1beta1/tx.proto#L50-L66 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/proto/cosmos/tx/v1beta1/tx.proto#L50-L67 ``` -* `NewAccount(uid, mnemonic, bip39Passphrase, hdPath string, algo SignatureAlgo) (*Record, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk. The `PrivKey` is **never stored unencrypted**, instead it is [encrypted with a passphrase](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/armor.go) before being persisted. In the context of this method, the key type and sequence number refers to the segment of the BIP44 derivation path (for example, `0`, `1`, `2`, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the same `PrivKey`, `PubKey` and `Address` is generated. The following keys are supported by the keyring: +* `NewAccount(uid, mnemonic, bip39Passphrase, hdPath string, algo SignatureAlgo) (*Record, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on selected backend. The `PrivKey` is **never stored unencrypted**, instead it is [encrypted with a passphrase](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.1/crypto/armor.go) before being persisted. In the context of this method, the key type and sequence number refers to the segment of the BIP44 derivation path (for example, `0`, `1`, `2`, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the same `PrivKey`, `PubKey` and `Address` is generated. The following keys are supported by the keyring: -* `secp256k1` -* `ed25519` + * `secp256k1` + * `ed25519` * `ExportPrivKeyArmor(uid, encryptPassphrase string) (armor string, err error)` exports a private key in ASCII-armored encrypted format using the given passphrase. You can then either import the private key again into the keyring using the `ImportPrivKey(uid, armor, passphrase string)` function or decrypt it into a raw private key using the `UnarmorDecryptPrivKey(armorStr string, passphrase string)` function. ### Create New Key Type -To create a new key type for using in keyring, `keyring.SignatureAlgo` interface must be fulfilled. +To create a new key type for use in the keyring, the `keyring.SignatureAlgo` interface must be fulfilled. ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keyring/signing_algorithms.go#L10-L15 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keyring/signing_algorithms.go#L11-L16 ``` The interface consists in three methods where `Name()` returns the name of the algorithm as a `hd.PubKeyType` and `Derive()` and `Generate()` must return the following functions respectively: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/hd/algo.go#L28-L31 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/hd/algo.go#L32-L35 ``` -Once the `keyring.SignatureAlgo` has been implemented it must be added to the [list of supported algos](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keyring/keyring.go#L217) of the keyring. +Once the `keyring.SignatureAlgo` has been implemented it must be added to the [list of supported algos](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keyring/keyring.go#L209) of the keyring. You can add your new algo to the list by using the [`Option` function](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keyring/keyring_other.go#L17). For simplicity the implementation of a new key type should be done inside the `crypto/hd` package. -There is an example of a working `secp256k1` implementation in [algo.go](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/hd/algo.go#L38). +There is an example of a working `secp256k1` implementation in [algo.go](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/hd/algo.go#L42-L79). #### Implementing secp256r1 algo @@ -238,21 +238,21 @@ func (s secp256r1Algo) Generate() GenerateFn { } ``` -Finally, the algo must be added to the list of [supported algos](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/crypto/keyring/keyring.go#L217) by the keyring. +Finally, the algo must be added to the list of [supported algos](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/crypto/keyring/keyring.go#L209) by the keyring. ```go // cosmos-sdk/crypto/keyring/keyring.go -func newKeystore(kr keyring.Keyring, cdc codec.Codec, backend string, opts ...Option) keystore { - // Default options for keybase, these can be overwritten using the - // Option function - options := Options{ - SupportedAlgos: SigningAlgoList{hd.Secp256k1, hd.Secp256r1}, // added here - SupportedAlgosLedger: SigningAlgoList{hd.Secp256k1}, +func setSupportedAlgos(algos SigningAlgoList) Option { + return func(options *Options) { + options.SupportedAlgos = algos } -... +} + +k, err := New("", "", "", userInput, cdc, setSupportedAlgos(SigningAlgoList{hd.Secp256k1, hd.Secp256r1})) + ``` -Hereafter to create new keys using your algo, you must specify it with the flag `--algo` : +Hereafter, to create new keys using your algo, you must specify it with the flag `--algo` : `simd keys add myKey --algo secp256r1` diff --git a/docs/learn/beginner/04-gas-fees.md b/docs/learn/beginner/04-gas-fees.md index 63ac006a839f..ea9af2e492b7 100644 --- a/docs/learn/beginner/04-gas-fees.md +++ b/docs/learn/beginner/04-gas-fees.md @@ -16,10 +16,10 @@ This document describes the default strategies to handle gas and fees within a C ## Introduction to `Gas` and `Fees` -In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: +In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever reads and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: * Make sure blocks are not consuming too many resources and are finalized. This is implemented by default in the Cosmos SDK via the [block gas meter](#block-gas-meter). -* Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../../build/building-modules/02-messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the Cosmos SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications implement `fee` mechanisms to prevent spam by using the [`AnteHandler`](#antehandler). +* Prevent spam and abuse from end-users. To this end, `gas` consumed during [`message`](../../build/building-modules/02-messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the Cosmos SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications implement `fee` mechanisms to prevent spam by using the [`AnteHandler`](#antehandler). ## Gas Meter @@ -84,18 +84,18 @@ The anteHandler is not implemented in the core Cosmos SDK but in a module. That * Verify that the transactions are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the transaction interface: ```go reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/tx_msg.go#L51-L56 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/types/tx_msg.go#L53-L66 ``` This enables developers to play with various types for the transaction of their application. In the default `auth` module, the default transaction type is `Tx`: ```protobuf reference -https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/tx/v1beta1/tx.proto#L14-L27 +https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/proto/cosmos/tx/v1beta1/tx.proto#L15-L28 ``` * Verify signatures for each [`message`](../../build/building-modules/02-messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. -* During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deduced from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensures that the mempool cannot be spammed with garbage transactions. +* During `CheckTx`, verify that the gas prices provided with the transaction are greater than the local `min-gas-prices` (as a reminder, gas-prices can be deduced from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensures that the mempool cannot be spammed with garbage transactions. * Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. * Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is crucial**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each transaction (`ctx` is set to `newCtx` after `anteHandler` is run, and the `anteHandler` is run each time a transactions executes). -As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`FinalizeBlock`](../advanced/00-baseapp.md#finalizeblock) returns. +As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed <= GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`FinalizeBlock`](../advanced/00-baseapp.md#finalizeblock) returns.