Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: update baseapp docs (part 2/2) #14790

Merged
merged 7 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 55 additions & 11 deletions docs/docs/core/00-baseapp.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,34 +131,55 @@ Naturally, developers can add additional `options` based on their application's
## State Updates

The `BaseApp` maintains two primary volatile states and a root or main state. The main state
samricotta marked this conversation as resolved.
Show resolved Hide resolved
is the canonical state of the application and the volatile states, `checkState` and `deliverState`,
is the canonical state of the application and the volatile states, `checkState`, `prepareProposalState`, `processPreposalState`,
samricotta marked this conversation as resolved.
Show resolved Hide resolved
are used to handle state transitions in-between the main state made during [`Commit`](#commit).

Internally, there is only a single `CommitMultiStore` which we refer to as the main or root state.
From this root state, we derive two volatile states by using a mechanism called _store branching_ (performed by `CacheWrap` function).
From this root state, we derive four volatile states by using a mechanism called _store branching_ (performed by `CacheWrap` function).
The types can be illustrated as follows:

![Types](./baseapp_state_types.png)
![Types](./baseapp_state.png)

### InitChain State Updates

During `InitChain`, the two volatile states, `checkState` and `deliverState` are set by branching
the root `CommitMultiStore`. Any subsequent reads and writes happen on branched versions of the `CommitMultiStore`.
During `InitChain`, the four volatile states, `checkState`, `prepareProposalState`, `processProposalState`
and `deliverState` are set by branching the root `CommitMultiStore`. Any subsequent reads and writes happen
on branched versions of the `CommitMultiStore`.
To avoid unnecessary roundtrip to the main state, all reads to the branched store are cached.

![InitChain](./baseapp_state-initchain.png)

### CheckTx State Updates

During `CheckTx`, the `checkState`, which is based off of the last committed state from the root
store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a service router
store, is used for any reads and writes. Here we only execute the `AnteHandler` and verify a service router
exists for every message in the transaction. Note, when we execute the `AnteHandler`, we branch
the already branched `checkState`.
This has the side effect that if the `AnteHandler` fails, the state transitions won't be reflected in the `checkState`
-- i.e. `checkState` is only updated on success.

![CheckTx](./baseapp_state-checktx.png)

### PrepareProposal State Updates

During `PrepareProposal`, the `prepareProposalState` is set by branching the root `CommitMultiStore`.
The `prepareProposalState` is used for any reads and writes that occur during the `PrepareProposal` phase.
The function uses the `Select()` method of the mempool to iterate over the transactions. `runTx` is then called,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's important to note that this is the behavior of the default handler and apps are free to choose and define their own as well.

Copy link
Member

@julienrbrt julienrbrt Jan 31, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, it is defined here: https://docs.cosmos.network/main/building-apps/app-mempool so it can simply be linked to.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes 100% i agree, ill include that for both prepare and process

which encodes and validates each transaction and from there the `AnteHandler` is executed.
If successful, valid transactions are returned inclusive of the events, tags, and data generated
during the execution of the proposal.

![ProcessProposal](./baseapp_state-prepareproposal.png)

### ProcessProposal State Updates

During `ProcessProposal`, the `processProposalState` is set based off of the last committed state
from the root store and is used to process a signed proposal received from a validator.
In this state, `runTx` is called and the `AnteHandler` is executed and the context used in this state is built with information
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

from the header and the main state, including the minimum gas prices, which are also set.

![ProcessProposal](./baseapp_state-processproposal.png)

### BeginBlock State Updates

During `BeginBlock`, the `deliverState` is set for use in subsequent `DeliverTx` ABCI messages. The
Expand Down Expand Up @@ -233,8 +254,30 @@ Developers building on top of the Cosmos SDK need not implement the ABCI themsel

### Prepare Proposal

The `PrepareProposal` function is part of the new methods introduced in Application Blockchain Interface (ABCI++) in Tendermint and is an important part of the application's overall governance system. In the Cosmos SDK, it allows the application to have more fine-grained control over the transactions that are processed, and ensures that only valid transactions are committed to the blockchain.

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.
5. 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 `DeliverTx()`, 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.

It's important to note that `PrepareProposal` complements the `ProcessProposal` method which is executed after this method. The combination of these two methods means that it is possible to guarantee that no invalid transactions are ever committed. Furthermore, such a setup can give rise to other interesting use cases such as Oracles, threshold decryption and more.

`PrepareProposal` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://github.com/tendermint/tendermint/blob/v0.37.x/spec/abci/abci++_methods.md#processproposal). The response contains:

- `Code (uint32)`: Response Code. `0` if successful.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: markdownlint.

- `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.


### Process Proposal
The `ProcessProposal` function is part of the new methods introduced in Application Blockchain Interface (ABCI++) in Tendermint. This function is called by the BaseApp as part of the ABCI message flow, and is executed during the `BeginBlock` phase of the consensus process. The purpose of this function is to give more control to the application for block validation, allowing it to check all transactions in a proposed block before the validator sends the prevote for the block. It allows a validator to perform application-dependent work in a proposed block, enabling features such as immediate block execution, and allows the Application to reject invalid blocks.

The `ProcessProposal` function is called by the BaseApp as part of the ABCI message flow, and is executed during the `BeginBlock` phase of the consensus process. The purpose of this function is to give more control to the application for block validation, allowing it to check all transactions in a proposed block before the validator sends the prevote for the block. It allows a validator to perform application-dependent work in a proposed block, enabling features such as immediate block execution, and allows the Application to reject invalid blocks.

The `ProcessProposal` function performs several key tasks, including:

Expand All @@ -253,10 +296,11 @@ However, developers must exercise greater caution when using these methods. Inco

`ProcessProposal` returns a response to the underlying consensus engine of type [`abci.ResponseCheckTx`](https://github.com/tendermint/tendermint/blob/v0.37.x/spec/abci/abci++_methods.md#processproposal). The response contains:

* `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.
- `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.


### CheckTx

Expand Down
Binary file modified docs/docs/core/baseapp_state-initchain.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/docs/core/baseapp_state.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed docs/docs/core/baseapp_state_types.png
Binary file not shown.