Skip to content

Commit

Permalink
docs: update some learn/advanced (#22255)
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianToledano authored Oct 15, 2024
1 parent 4274dcf commit 77254b7
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 74 deletions.
43 changes: 21 additions & 22 deletions docs/learn/advanced/00-baseapp.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ management logic.

The `BaseApp` type holds many important parameters for any Cosmos SDK based application.

https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/baseapp.go#L58-L182
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/baseapp.go#L63-L191

Let us go through the most important components.

Expand All @@ -71,7 +71,7 @@ First, the important parameters that are initialized during the bootstrapping of
* [gRPC Query Router](#grpc-query-router): The `grpcQueryRouter` facilitates the routing of gRPC queries to the
appropriate module for it to be processed. These queries are not ABCI messages themselves, but they
are relayed to the relevant module's gRPC `Query` service.
* [`TxDecoder`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/types#TxDecoder): It is used to decode
* [`TxDecoder`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.52.0-beta.2/types#TxDecoder): It is used to decode
raw transaction bytes relayed by the underlying CometBFT engine.
* [`AnteHandler`](#antehandler): This handler is used to handle signature verification, fee payment,
and other pre-message execution checks when a transaction is received. It's executed during
Expand Down Expand Up @@ -216,15 +216,15 @@ When messages and queries are received by the application, they must be routed t

[`sdk.Msg`s](../../build/building-modules/02-messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying CometBFT engine via the [`CheckTx`](#checktx) and [`FinalizeBlock`](#finalizeblock) ABCI messages. To do so, `BaseApp` holds a `msgServiceRouter` which maps fully-qualified service methods (`string`, defined in each module's Protobuf `Msg` service) to the appropriate module's `MsgServer` implementation.

The [default `msgServiceRouter` included in `BaseApp`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/msg_service_router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into each [route handler inside `msgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/msg_service_router.go#L31-L32). For a stateless router that doesn't want to make use of this, you can just ignore the `ctx`.
The [default `msgServiceRouter` included in `BaseApp`](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/msg_service_router.go) is stateless. However, some applications may want to make use of more stateful routing mechanisms such as allowing governance to disable certain routes or point them to new modules for upgrade purposes. For this reason, the `sdk.Context` is also passed into each [route handler inside `msgServiceRouter`](https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/msg_service_router.go#L42). For a stateless router that doesn't want to make use of this, you can just ignore the `ctx`.

The application's `msgServiceRouter` is initialized with all the routes using the application's [module manager](../../build/building-modules/01-module-manager.md#manager) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../beginner/00-app-anatomy.md#constructor-function).

### gRPC Query Router

Similar to `sdk.Msg`s, [`queries`](../../build/building-modules/02-messages-and-queries.md#queries) need to be routed to the appropriate module's [`Query` service](../../build/building-modules/04-query-services.md). To do so, `BaseApp` holds a `grpcQueryRouter`, which maps modules' fully-qualified service methods (`string`, defined in their Protobuf `Query` gRPC) to their `QueryServer` implementation. The `grpcQueryRouter` is called during the initial stages of query processing, which can be either by directly sending a gRPC query to the gRPC endpoint, or via the [`Query` ABCI message](#query) on the CometBFT RPC endpoint.

Just like the `msgServiceRouter`, the `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../../build/building-modules/01-module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../beginner/00-app-anatomy.md#app-constructor).
Just like the `msgServiceRouter`, the `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../../build/building-modules/01-module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../beginner/00-app-anatomy.md#constructor-function).

## Main ABCI 2.0 Messages

Expand All @@ -237,7 +237,7 @@ The consensus engine handles two main tasks:

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:
Developers building on top of the Cosmos SDK don't need to 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:

* [`Prepare Proposal`](#prepare-proposal)
* [`Process Proposal`](#process-proposal)
Expand All @@ -255,7 +255,7 @@ Here is how the `PrepareProposal` function can be implemented:

1. Extract the `sdk.Msg`s from the transaction.
2. Perform _stateful_ checks by calling `Validate()` on each of the `sdk.Msg`'s. This is done after _stateless_ checks as _stateful_ checks are more computationally expensive. If `Validate()` fails, `PrepareProposal` returns before running further checks, which saves resources.
3. Perform any additional checks that are specific to the application, such as checking account balances, or ensuring that certain conditions are met before a transaction is proposed.hey are processed by the consensus engine, if necessary.
3. Perform any additional checks that are specific to the application, such as checking account balances, or ensuring that certain conditions are met before a transaction is proposed. They are processed by the consensus engine, if necessary.
4. Return the updated transactions to be processed by the consensus engine

Note that, unlike `CheckTx()`, `PrepareProposal` process `sdk.Msg`s, so it can directly update the state. However, unlike `FinalizeBlock()`, it does not commit the state updates. It's important to exercise caution when using `PrepareProposal` as incorrect coding could affect the overall liveness of the network.
Expand Down Expand Up @@ -289,7 +289,7 @@ However, developers must exercise greater caution when using these methods. Inco

* `Status (ProposalStatus)`: Status of the proposal processing

where `ProposalStatus` can be one of the following status value:
where `ProposalStatus` can be one of the [following status value](https://docs.cometbft.com/v1.0/spec/abci/abci++_methods#proposalstatus):

```
enum ProposalStatus {
Expand All @@ -311,7 +311,7 @@ make the checks **lightweight** because gas fees are not charged for the resourc

The [`Context`](../advanced/02-context.md), which includes a `GasMeter` that tracks how much gas is used during the execution of `Tx`, is initialized at the beginning of `CheckTx`. The user-provided amount of gas for `Tx` is referred to as `GasWanted`. If `GasConsumed`, the amount of gas used during execution, exceeds `GasWanted`, the execution is halted and the changes made to the cached copy of the state are not committed. Otherwise, `CheckTx` sets `GasUsed` equal to `GasConsumed` and returns it in the result. After calculating the gas and fee values, validator-nodes ensure that the user-specified `gas-prices` exceed their locally defined `min-gas-prices`.

In the Cosmos SDK, after [decoding transactions](https://docs.cosmos.network/main/learn/advanced/encoding), `CheckTx()` is implemented
In the Cosmos SDK, after [decoding transactions](./05-encoding.md), `CheckTx()` is implemented
to do the following checks:

1. Extract the `sdk.Msg`s from the transaction.
Expand Down Expand Up @@ -351,7 +351,7 @@ The response contains:
* `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. Next is an example:

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/ante/basic.go#L102
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/auth/ante/basic.go#L141-L144
```

* `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`events`](./08-events.md) for more.
Expand Down Expand Up @@ -379,7 +379,7 @@ After that, `RunTx()` calls `ValidateBasic()`, when available and for backward c
Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`finalizeBlockState`'s `context` and `context`'s `CacheMultiStore` are branched using the `cacheTxContext()` function.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/baseapp.go#L663-L680
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/baseapp.go#L683-L699
```

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](./10-ocap.md) of the Cosmos SDK.
Expand All @@ -403,12 +403,12 @@ These operations are crucial for maintaining the security and integrity of trans
For more detailed examples, see the [`auth` module's `AnteHandler`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth) which is widely used for these purposes.

:::warning
Ante handlers typically operate at the transaction level. By default, they process only the outermost message of a transaction. However, transactions that embed multiple messages, such as those found in modules like x/authz or x/gov, may have inner messages that are not automatically processed by these default ante handlers. These inner messages are generally routed directly to the [message router](https://docs.cosmos.network/main/learn/advanced/baseapp#msg-service-router) bypassing the ante handlers. To ensure comprehensive processing, custom ante handlers can be designed to recursively inspect and apply necessary checks to all embedded messages within a transaction. This capability must be explicitly implemented to extend the awareness of ante handlers to inner messages.
Ante handlers typically operate at the transaction level. By default, they process only the outermost message of a transaction. However, transactions that embed multiple messages, such as those found in modules like x/authz or x/gov, may have inner messages that are not automatically processed by these default ante handlers. These inner messages are generally routed directly to the [message router](#msg-service-router) bypassing the ante handlers. To ensure comprehensive processing, custom ante handlers can be designed to recursively inspect and apply necessary checks to all embedded messages within a transaction. This capability must be explicitly implemented to extend the awareness of ante handlers to inner messages.
:::

The `AnteHandler` is a primary line of defense against spam and a second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./01-transactions.md#transaction-generation) checking. It also performs preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees, and plays a role in the incentivisation of stakeholders via the collection of transaction fees.

`BaseApp` holds an `anteHandler` as parameter that is initialized in the [application's constructor](../beginner/00-app-anatomy.md#application-constructor). The most widely used `anteHandler` is the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/ante/ante.go).
`BaseApp` holds an `anteHandler` as parameter that is initialized in the [application's constructor](../beginner/00-app-anatomy.md#constructor-function). The most widely used `anteHandler` is the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/ante/ante.go).

Click [here](../beginner/04-gas-fees.md#antehandler) for more on the `anteHandler`.

Expand All @@ -431,7 +431,7 @@ Like `AnteHandler`s, `PostHandler`s are theoretically optional.
Other use cases like unused gas refund can also be enabled by `PostHandler`s.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/posthandler/post.go#L1-L15
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/x/auth/posthandler/post.go#L1-L15
```

Note, when `PostHandler`s fail, the state from `runMsgs` is also reverted, effectively making the transaction fail.
Expand All @@ -455,25 +455,25 @@ The [`FinalizeBlock` ABCI message](https://docs.cometbft.com/v1.0/spec/abci/abci


```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci.go#L623
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/abci.go#L894
```

#### PreBlock

* Run the application's [`preBlocker()`](../beginner/00-app-anatomy.md#preblocker), which mainly runs the [`PreBlocker()`](../../build/building-modules/06-preblock-beginblock-endblock.md#preblock) method of each of the modules.
* Run the application's [`preBlocker()`](../beginner/00-app-anatomy.md#preblocker), which mainly runs the [`PreBlocker()`](../../build/building-modules/06-preblock-beginblock-endblock.md#preblocker) method of each of the modules.

#### BeginBlock

* Initialize [`finalizeBlockState`](#state-updates) with the latest header using the `req abci.RequestFinalizeBlock` passed as parameter via the `setState` function.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/baseapp.go#L682-L706
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/baseapp.go#L729-L754
```

This function also resets the [main gas meter](../beginner/04-gas-fees.md#main-gas-meter).

* Initialize the [block gas meter](../beginner/04-gas-fees.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 [`beginBlocker()`](../beginner/00-app-anatomy.md#beginblocker-and-endblocker), which mainly runs the [`BeginBlocker()`](../../build/building-modules/06-preblock-beginblock-endblock.md#beginblock) method of each of the modules.
* Run the application's [`beginBlocker()`](../beginner/00-app-anatomy.md#beginblocker-and-endblocker), which mainly runs the [`BeginBlocker()`](../../build/building-modules/06-preblock-beginblock-endblock.md#beginblocker-and-endblocker) method of each of the modules.
* Set the [`VoteInfos`](https://docs.cometbft.com/v1.0/spec/abci/abci++_methods#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`](./02-context.md) so that it can be used during transaction execution and EndBlock.

#### Transaction Execution
Expand All @@ -490,8 +490,7 @@ The `FinalizeBlock` ABCI function defined in `BaseApp` does the bulk of the stat

Instead of using their `checkState`, full-nodes use `finalizeblock`:

https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/baseapp.go#LL708-L743

https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/baseapp.go#L756-L791

Transaction execution within `FinalizeBlock` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step:

Expand All @@ -501,7 +500,7 @@ Transaction execution within `FinalizeBlock` performs the **exact same steps as
During the additional fifth step outlined in (2), each read/write to the store increases the value of `GasConsumed`. You can find the default cost of each operation:

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/store/types/gas.go#L230-L241
https://github.com/cosmos/cosmos-sdk/blob/store/v1.1.1/store/types/gas.go#L231-L242
```

At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and the execution fails.
Expand All @@ -524,7 +523,7 @@ Each transaction returns a response to the underlying consensus engine of type [
EndBlock is run after transaction execution completes. It allows developers to have logic be executed at the end of each block. In the Cosmos SDK, the bulk EndBlock() method is to run the application's EndBlocker(), which mainly runs the EndBlocker() method of each of the application's modules.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/baseapp.go#L747-L769
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/baseapp.go#L729-L754
```

### Commit
Expand Down Expand Up @@ -560,7 +559,7 @@ Each CometBFT `query` comes with a `path`, which is a `string` which denotes wha
In the Cosmos-SDK this is implemented as a NoOp:

``` go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci_utils.go#L274-L281
https://github.com/cosmos/cosmos-sdk/blob/v0.52.0-beta.2/baseapp/abci_utils.go#L456-L462
```

### VerifyVoteExtension
Expand Down
Loading

0 comments on commit 77254b7

Please sign in to comment.