Skip to content

Commit

Permalink
docs: improve mempool docs (backport #14282) (#14319)
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] authored Dec 15, 2022
1 parent da4a734 commit 15a817c
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 19 deletions.
91 changes: 74 additions & 17 deletions docs/docs/building-apps/02-app-mempool.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ sidebar_position: 1
This sections describes how the app side mempool can be used and replaced.
:::


Since `0.47` the application has its own mempool to allow much more granular block building than previous versions. This change was enabled by [ABCI 1.0](https://github.com/tendermint/tendermint/blob/main/spec/abci/README.md). Notably it introduces the prepare and process proposal steps of ABCI.
Since `v0.47` the application has its own mempool to allow much more granular block building than previous versions. This change was enabled by [ABCI 1.0](https://github.com/tendermint/tendermint/blob/main/spec/abci/README.md). Notably it introduces the prepare and process proposal steps of ABCI.

## Prepare Proposal

Expand All @@ -18,15 +17,18 @@ Prepare proposal handles construction of the block, meaning that when a proposer
Currently, there is a default `PrepareProposal` implementation provided by the application.

```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/baseapp.go#L866-L904
https://github.com/cosmos/cosmos-sdk/blob/main/baseapp/baseapp.go#L870-L908
```

This default implementation can be overridden by the application developer in favor of a custom implementation:
This default implementation can be overridden by the application developer in favor of a custom implementation in [`app.go`](./01-app-go-v2.md):

```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/simapp/app.go#L197-L199
```
```go
prepareOpt := func(app *baseapp.BaseApp) {
app.SetPrepareProposal(app.DefaultPrepareProposal())
}

baseAppOptions = append(baseAppOptions, prepareOpt)
```

## Process Proposal

Expand All @@ -35,29 +37,84 @@ Process proposal handles the validation of what is in a block, meaning that afte
Here is the implementation of the default implementation:

```go reference
https://github.com/cosmos/cosmos-sdk/blob/bcff22a3767b9c5dd7d1d562aece90cf72e05e85/baseapp/baseapp.go#L906-L930
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-alpha2/baseapp/baseapp.go#L911-L935
```

Like `PrepareProposal` this implementation is the default and can be modified by the application developer.
Like `PrepareProposal` this implementation is the default and can be modified by the application developer in [`app.go`](./01-app-go-v2.md):

```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/simapp/app.go#L200-L203
```go
processOpt := func(app *baseapp.BaseApp) {
app.SetProcessProposal(app.DefaultProcessProposal())
}

baseAppOptions = append(baseAppOptions, processOpt)
```

## Mempool

Now that we have walked through the `PrepareProposal` & `ProcessProposal`, we can move on to walking through the mempool.

There are countless designs that an application developer can write for a mempool, the core team opted to provide a simple implementation of a nonce mempool. The nonce mempool is a mempool that keeps transactions from an sorted by nonce in order to avoid the issues with nonces.
There are countless designs that an application developer can write for a mempool, the SDK opted to provide only simple mempool implementations.
Namely, the SDK provides the following mempools:

* [No-op Mempool](#no-op-mempool)
* [Sender Nonce Mempool](#sender-nonce-mempool)
* [Priority Nonce Mempool](#priority-nonce-mempool)

The default SDK is a [No-op Mempool](#no-op-mempool), but it can be replaced by the application developer in [`app.go`](./01-app-go-v2.md):

```go
nonceMempool := mempool.NewSenderNonceMempool()
mempoolOpt := baseapp.SetMempool(nonceMempool)
baseAppOptions = append(baseAppOptions, mempoolOpt)
```

### No-op Mempool

A no-op mempool is a mempool where transactions are completely discarded and ignored when BaseApp interacts with the mempool.
When this mempool is used, it assumed that an application will rely on Tendermint's transaction ordering defined in `RequestPrepareProposal`,
which is FIFO-ordered by default.

### Sender Nonce Mempool

The nonce mempool is a mempool that keeps transactions from an sorted by nonce in order to avoid the issues with nonces.
It works by storing the transation in a list sorted by the transaction nonce. When the proposer asks for transactions to be included in a block it randomly selects a sender and gets the first transaction in the list. It repeats this until the mempool is empty or the block is full.

### Configurations
It is configurable with the following parameters:

#### MaxTxs

Its an integer value that sets the mempool in one of three modes, bounded, unbounded, or disabled.
It is an integer value that sets the mempool in one of three modes, *bounded*, *unbounded*, or *disabled*.

* **negative**: Disabled, mempool does not insert new transaction and return early.
* **zero**: Unbounded mempool has no transaction limit and will never fail with `ErrMempoolTxMaxCapacity`.
* **positive**: Bounded, it fails with `ErrMempoolTxMaxCapacity` when `maxTx` value is the same as `CountTx()`

#### Seed

Set the seed for the random number generator used to select transactions from the mempool.

### Priority Nonce Mempool

The [priority nonce mempool](https://github.com/cosmos/cosmos-sdk/blob/main/types/mempool/priority_nonce_spec.md) is a mempool implementation that stores txs in a partially ordered set by 2 dimensions:

* priority
* sender-nonce (sequence number)

Internally it uses one priority ordered [skip list](https://pkg.go.dev/github.com/huandu/skiplist) and one skip list per sender ordered by sender-nonce (sequence number). When there are multiple txs from the same sender, they are not always comparable by priority to other sender txs and must be partially ordered by both sender-nonce and priority.

It is configurable with the following parameters:

#### MaxTxs

It is an integer value that sets the mempool in one of three modes, *bounded*, *unbounded*, or *disabled*.

* **negative**: Disabled, mempool does not insert new transaction and return early.
* **zero**: Unbounded mempool has no transaction limit and will never fail with `ErrMempoolTxMaxCapacity`.
* **positive**: Bounded, it fails with `ErrMempoolTxMaxCapacity` when `maxTx` value is the same as `CountTx()`

#### Callback

Allow to set a callback to be called when a transaction is read from the mempool.

- **negative**: Disabled, mempool does not insert new tx and return early.
- **zero**: Unbounded mempool has no tx limit and will never fail with ErrMempoolTxMaxCapacity.
- **positive**: Bounded, it fails with ErrMempoolTxMaxCapacity when maxTx value is the same as CountTx()
More information on the SDK mempool implementation can be found in the [godocs](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/types/mempool).
4 changes: 2 additions & 2 deletions types/mempool/priority_nonce.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ var (
_ Iterator = (*priorityNonceIterator)(nil)
)

// priorityNonceMempool defines the SDK's default mempool implementation which stores
// txs in a partially ordered set by 2 dimensions: priority, and sender-nonce
// priorityNonceMempool is a mempool implementation that stores txs
// in a partially ordered set by 2 dimensions: priority, and sender-nonce
// (sequence number). Internally it uses one priority ordered skip list and one
// skip list per sender ordered by sender-nonce (sequence number). When there
// are multiple txs from the same sender, they are not always comparable by
Expand Down

0 comments on commit 15a817c

Please sign in to comment.