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

## Description

 

- [x] Update baseapp documentation and add mention of ProcessProposal
- [x] Update baseapp documentation and add mention of PrepareProposal
- [x] Update diagrams using draw.io (and save the diagrams in the png for future easy modification)
- [x] Ensure there is no duplicate explanation between https://docs.cosmos.network/main/core/baseapp vs https://docs.cosmos.network/main/building-apps/app-mempool (where the later should focus more on the app customization)

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
This commit is contained in:
samricotta 2023-02-01 11:26:11 +01:00 committed by GitHub
parent b266522c88
commit d2e23d0ff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 12 deletions

View File

@ -130,20 +130,21 @@ 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
is the canonical state of the application and the volatile states, `checkState` and `deliverState`,
The `BaseApp` maintains four primary volatile states and a root or main state. The main state
is the canonical state of the application and the volatile states, `checkState`, `deliverState`, `prepareProposalState`, `processPreposalState`,
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)
@ -151,7 +152,7 @@ To avoid unnecessary roundtrip to the main state, all reads to the branched stor
### 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`
@ -159,6 +160,30 @@ This has the side effect that if the `AnteHandler` fails, the state transitions
![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,
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.
The described behavior is that of the default handler, applications have the flexibility to define their own
[custom mempool handlers](https://docs.cosmos.network/main/building-apps/app-mempool#custom-mempool-handlers).
![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
from the header and the main state, including the minimum gas prices, which are also set.
Again we want to highlight that the described behavior is that of the default handler and applications have the flexibility to define their own
[custom mempool handlers](https://docs.cosmos.network/main/building-apps/app-mempool#custom-mempool-handlers).
![ProcessProposal](./baseapp_state-processproposal.png)
### BeginBlock State Updates
During `BeginBlock`, the `deliverState` is set for use in subsequent `DeliverTx` ABCI messages. The
@ -233,8 +258,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.
* `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:
@ -253,10 +300,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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB