-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
## Description Closes: #9954 --- ### 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... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [x] 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/master/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/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/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)
- Loading branch information
1 parent
44a1293
commit 8c65b79
Showing
13 changed files
with
171 additions
and
11 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 8 | ||
order: 9 | ||
--> | ||
|
||
# Command-Line Interface | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 6 | ||
order: 7 | ||
--> | ||
|
||
# Encoding | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 9 | ||
order: 10 | ||
--> | ||
|
||
# Events | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 7 | ||
order: 8 | ||
--> | ||
|
||
# gRPC, REST, and Tendermint Endpoints | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
<!-- | ||
order: 3 | ||
--> | ||
|
||
# Middlewares | ||
|
||
|
||
`Middlewares` are objects that the developer can create to add logic before or after the transaction handler in a composable manner. | ||
{synopsis} | ||
|
||
## Pre-requisite Readings | ||
|
||
* [Anatomy of a Cosmos SDK Application](../basics/app-anatomy.md) {prereq} | ||
* [Transactons](transactions.md){prereq} | ||
|
||
|
||
## Middlewares | ||
|
||
The SDK Baseapp's implementation of ABCI CheckTx, DeliverTx, and Baseapp's own Simulate methods use a middleware-based design. Middlewares can add logic to be executed before or after a transaction handler execution. Middlewares are like an `antehandler` with the added feature of being able to add post-transaction handler execution. Middlewares allow us to solve use cases like transaction Tips and refund unused gas (issue [#2150](https://github.com/cosmos/cosmos-sdk/issues/2150)). | ||
|
||
|
||
### Type Definition | ||
|
||
The two following interfaces are the base of the middleware design, and are defined in types/tx: | ||
|
||
+++ https://github.com/cosmos/cosmos-sdk/blob/5491be27d02e796746bd78d3d08bd1b2a9b1deb2/types/tx/middleware.go#L62-L71 | ||
|
||
Where we define the following arguments and return types: | ||
|
||
+++ https://github.com/cosmos/cosmos-sdk/blob/5491be27d02e796746bd78d3d08bd1b2a9b1deb2/types/tx/middleware.go#L25-L60 | ||
|
||
BaseApp holds a reference to a `tx.Handler`, which will process the incoming transactions. It could be a simple `sdk.Msg` executor, but in practice, it will be defined as a middleware stack wrapping around the base `sdk.Msg` executor. | ||
|
||
```go | ||
type BaseApp struct { | ||
// other fields | ||
txHandler tx.Handler | ||
} | ||
``` | ||
|
||
|
||
## Implementing a Middleware | ||
|
||
To implement a middleware is done simply by a Go function that takes as arguments and some parameters and returns a `tx.Middleware`. | ||
|
||
For example, we can create a Generic middleware. | ||
|
||
```go | ||
// myTxHandler is the tx.Handler of this middleware. Note that it holds a | ||
// reference to the next tx.Handler in the stack. | ||
type myTxHandler struct { | ||
// next is the next tx.Handler in the middleware stack. | ||
next tx.Handler | ||
// some other fields that are relevant to the middleware can be added here | ||
} | ||
|
||
// NewMyMiddleware returns a middleware that does this and that. | ||
func NewMyMiddleware(arg1, arg2) tx.Middleware { | ||
return func (txh tx.Handler) tx.Handler { | ||
return myTxHandler{ | ||
next: txh, | ||
// optionally, set arg1, arg2... if they are needed in the middleware | ||
} | ||
} | ||
} | ||
|
||
// Assert myTxHandler is a tx.Handler. | ||
var _ tx.Handler = myTxHandler{} | ||
``` | ||
|
||
Next we need to implement the middleware [interface](#Type-Definition). | ||
|
||
```go | ||
func (h myTxHandler) CheckTx(ctx context.Context, req Request, checkReq RequestcheckTx) (Response, ResponseCheckTx, error) { | ||
// CheckTx specific pre-processing logic | ||
|
||
// run the next middleware | ||
res, checkRes, err := txh.next.CheckTx(ctx, req, checkReq) | ||
|
||
// CheckTx specific post-processing logic | ||
|
||
return res, checkRes, err | ||
} | ||
|
||
func (h myTxHandler) DeliverTx(ctx context.Context, req Request) (Response, error) { | ||
// DeliverTx specific pre-processing logic | ||
|
||
// run the next middleware | ||
res, err := txh.next.DeliverTx(ctx, tx, req) | ||
|
||
// DeliverTx specific post-processing logic | ||
|
||
return res, err | ||
} | ||
|
||
func (h myTxHandler) SimulateTx(ctx context.Context, req Request) (Response, error) { | ||
// SimulateTx specific pre-processing logic | ||
|
||
// run the next middleware | ||
res, err := txh.next.SimulateTx(ctx, tx, req) | ||
|
||
// SimulateTx specific post-processing logic | ||
|
||
return res, err | ||
} | ||
``` | ||
|
||
### Composing Middlewares | ||
|
||
While BaseApp holds a reference to a `tx.Handler`, this `tx.Handler` itself is defined using a middleware stack. The Cosmos SDK exposes a base (i.e. innermost) `tx.Handler` called `RunMsgsTxHandler`, which executes messages. It holds a reference to the `MsgServiceRouter`, which is used to map each `sdk.Msg` to the correct module's `Msg` server handler. | ||
|
||
Then, the app developer can compose multiple middlewares on top of the base `tx.Handler`. Each middleware can run pre-and-post-processing logic around its next middleware, as described in the section above. Conceptually, as an example, given the middlewares `A`, `B`, and `C` and the base `tx.Handler` `H` the stack looks like: | ||
|
||
 | ||
|
||
```text | ||
A.pre | ||
B.pre | ||
C.pre | ||
Handler # The base tx.handler, for example `RunMsgsTxHandler` | ||
C.post | ||
B.post | ||
A.post | ||
``` | ||
|
||
We define a `ComposeMiddlewares` function for composing middlewares. It takes the base handler as first argument, and middlewares in the "outer to inner" order. For the above stack, the final `tx.Handler` is: | ||
|
||
```go | ||
txHandler := middleware.ComposeMiddlewares(H, A, B, C) | ||
``` | ||
|
||
The middleware is set in BaseApp via its `SetTxHandler` setter: | ||
|
||
```go | ||
// simapp/app.go | ||
|
||
txHandler := middleware.ComposeMiddlewares(...) | ||
app.SetTxHandler(txHandler) | ||
``` | ||
|
||
The app developer can define their own middlewares, or use the Cosmos SDK's pre-defined middlewares from `middleware.NewDefaultTxHandler()`. | ||
|
||
### Middlewares Maintained by the Cosmos SDK | ||
|
||
While the app developer can define and compose the middlewares of their choice, the Cosmos SDK provides a set of middlewares that caters to the ecosystem's most common use cases. These middlewares are: | ||
|
||
| Middleware | Description | | ||
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| RunMsgsTxHandler | This is the base `tx.Handler`. It replaces the old baseapp's `runMsgs`, and executes a transaction's `Msg`s. | | ||
| TxDecoderMiddleware | This middleware takes in transaction raw bytes, and decodes them into a `sdk.Tx`. It replaces the `baseapp.txDecoder` field, so that BaseApp stays as thin as possible. Since most middlewares read the contents of the `sdk.Tx`, the TxDecoderMiddleware should be run first in the middelware stack. | | ||
| {Antehandlers} | Each antehandler is converted to its own middleware. These middlewares perform signature verification, fee deductions and other validations on the incoming transaction. | | ||
| IndexEventsTxMiddleware | This is a simple middleware that chooses which events to index in Tendermint. Replaces `baseapp.indexEvents` (which unfortunately still exists in baseapp too, because it's used to index Begin/EndBlock events) | | ||
| RecoveryTxMiddleware | This index recovers from panics. It replaces baseapp.runTx's panic recovery described in [ADR-022](./adr-022-custom-panic-handling.md). | | ||
| GasTxMiddleware | This replaces the [`Setup`](https://github.com/cosmos/cosmos-sdk/blob/v0.43.0/x/auth/ante/setup.go) Antehandler. It sets a GasMeter on sdk.Context. Note that before, GasMeter was set on sdk.Context inside the antehandlers, and there was some mess around the fact that antehandlers had their own panic recovery system so that the GasMeter could be read by baseapp's recovery system. Now, this mess is all removed: one middleware sets GasMeter, another one handles recovery. | ||
| TipMiddleware | This pays for transaction fees using another denom than the native fee denom of the chain. [`docs`](tips.md) | ||
| SigGasConsumeMiddleware | SigGasConsumeMiddleware consumes parameter-defined amount of gas for each signature. | ||
| SigVerificationMiddleware | verifies all signatures for a tx and return an error if any are invalid | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 4 | ||
order: 5 | ||
--> | ||
|
||
# Node Client (Daemon) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 11 | ||
order: 12 | ||
--> | ||
|
||
# Object-Capability Model | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 14 | ||
order: 16 | ||
--> | ||
|
||
# Protobuf Documentation | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 12 | ||
order: 13 | ||
--> | ||
|
||
# RunTx recovery middleware | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 13 | ||
order: 14 | ||
--> | ||
|
||
# Cosmos Blockchain Simulator | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 5 | ||
order: 6 | ||
--> | ||
|
||
# Store | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
<!-- | ||
order: 10 | ||
order: 11 | ||
--> | ||
|
||
# Telemetry | ||
|