diff --git a/docs/basics/accounts.md b/docs/basics/accounts.md index 2ee844c83203..da3251dc4e59 100644 --- a/docs/basics/accounts.md +++ b/docs/basics/accounts.md @@ -131,16 +131,16 @@ For user interactions, `PubKey` is formatted using Protobufs JSON ([ProtoMarshal A `Keyring` is an object that stores and manages accounts. In the Cosmos SDK, a `Keyring` implementation follows the `Keyring` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/crypto/keyring/keyring.go#L54-L101 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/crypto/keyring/keyring.go#L53-L101 The default implementation of `Keyring` comes from the third-party [`99designs/keyring`](https://github.com/99designs/keyring) library. A few notes on the `Keyring` methods: -* `Sign(uid string, msg []byte) ([]byte, types.PubKey, error)` strictly deals with the signature of the `msg` bytes. You must prepare and encode the transaction into a canonical `[]byte` form. Because protobuf is not deterministic, it has been decided in [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) that the canonical `payload` to sign is the `SignDoc` struct, deterministically encoded using [ADR-027](../architecture/adr-027-deterministic-protobuf-serialization.md). Note that signature verification is not implemented in the Cosmos SDK by default, it is deferred to the [`SigVerificationMiddleware middleware`](../core/baseapp.md#middleware). - +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/tx/v1beta1/tx.proto#L49-L64 +* `Sign(uid string, msg []byte) ([]byte, types.PubKey, error)` strictly deals with the signature of the `msg` bytes. You must prepare and encode the transaction into a canonical `[]byte` form. Because protobuf is not deterministic, it has been decided in [ADR-020](../architecture/adr-020-protobuf-transaction-encoding.md) that the canonical `payload` to sign is the `SignDoc` struct, deterministically encoded using [ADR-027](../architecture/adr-027-deterministic-protobuf-serialization.md). Note that signature verification is not implemented in the Cosmos SDK by default, it is deferred to the [`anteHandler`](../core/baseapp.md#antehandler). + +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/tx/v1beta1/tx.proto#L48-L65 -* `NewAccount(uid, mnemonic, bip39Passphrase, hdPath string, algo SignatureAlgo) (*Record, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk. The `PrivKey` is **never stored unencrypted**, instead it is [encrypted with a passphrase](https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/crypto/armor.go) before being persisted. In the context of this method, the key type and sequence number refer to the segment of the BIP44 derivation path (for example, `0`, `1`, `2`, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the same `PrivKey`, `PubKey` and `Address` is generated. The following keys are supported by the keyring: +* `NewAccount(uid, mnemonic, bip39Passphrase, hdPath string, algo SignatureAlgo) (*Record, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk. The `PrivKey` is **never stored unencrypted**, instead it is [encrypted with a passphrase](https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/crypto/armor.go) before being persisted. In the context of this method, the key type and sequence number refer to the segment of the BIP44 derivation path (for example, `0`, `1`, `2`, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the same `PrivKey`, `PubKey` and `Address` is generated. The following keys are supported by the keyring: * `secp256k1` * `ed25519` diff --git a/docs/basics/app-anatomy.md b/docs/basics/app-anatomy.md index ab7dfc55c68e..f589ee76c7ea 100644 --- a/docs/basics/app-anatomy.md +++ b/docs/basics/app-anatomy.md @@ -53,13 +53,13 @@ The first thing defined in `app.go` is the `type` of the application. It is gene See an example of application type definition from `simapp`, the Cosmos SDK's own app used for demo and testing purposes: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/simapp/app.go#L151-L195 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/simapp/app.go#L151-L193 ### Constructor Function This function constructs a new application of the type defined in the section above. It must fulfill the `AppCreator` signature in order to be used in the [`start` command](../core/node.md#start-command) of the application's daemon command. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/server/types/app.go#L57-L59 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/server/types/app.go#L57-L59 Here are the main actions performed by this function: @@ -73,7 +73,7 @@ Here are the main actions performed by this function: * Set the remainder of application's parameters: * [`InitChainer`](#initchainer): used to initialize the application when it is first started. * [`BeginBlocker`, `EndBlocker`](#beginblocker-and-endlbocker): called at the beginning and the end of every block). - * [`TxHandler`](../core/baseapp.md#middleware): to setup middlewares, f.e. used to handle fees and signature verification. + * [`anteHandler`](../core/baseapp.md#antehandler): used to handle fees and signature verification. * Mount the stores. * Return the application. @@ -81,7 +81,7 @@ Note that this function only creates an instance of the app, while the actual st See an example of application constructor from `simapp`: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/simapp/app.go#L207-L456 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/simapp/app.go#L204-L474 ### InitChainer @@ -146,7 +146,7 @@ Note that `sdk.Msg`s are bundled in [transactions](../core/transactions.md), and When a valid block of transactions is received by the full-node, Tendermint relays each one to the application via [`DeliverTx`](https://docs.tendermint.com/master/spec/abci/apps.html#delivertx). Then, the application handles the transaction: 1. Upon receiving the transaction, the application first unmarshalls it from `[]byte`. -2. Then, it verifies a few things about the transaction like [fee payment and signatures](./gas-fees.md#middleware) before extracting the `Msg`(s) contained in the transaction. +2. Then, it verifies a few things about the transaction like [fee payment and signatures](./gas-fees.md#antehandler) before extracting the `Msg`(s) contained in the transaction. 3. `sdk.Msg`s are encoded using Protobuf [`Any`s](#register-codec). By analyzing each `Any`'s `type_url`, baseapp's `msgServiceRouter` routes the `sdk.Msg` to the corresponding module's `Msg` service. 4. If the message is successfully processed, the state is updated. diff --git a/docs/basics/gas-fees.md b/docs/basics/gas-fees.md index 10205cf92996..4b011be614bf 100644 --- a/docs/basics/gas-fees.md +++ b/docs/basics/gas-fees.md @@ -15,7 +15,7 @@ This document describes the default strategies to handle gas and fees within a C In the Cosmos SDK, `gas` is a special unit that is used to track the consumption of resources during execution. `gas` is typically consumed whenever read and writes are made to the store, but it can also be consumed if expensive computation needs to be done. It serves two main purposes: * Make sure blocks are not consuming too many resources and will be finalized. This is implemented by default in the Cosmos SDK via the [block gas meter](#block-gas-meter). -* Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the Cosmos SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`GasTxMiddleware` middleware](#middleware). +* Prevent spam and abuse from end-user. To this end, `gas` consumed during [`message`](../building-modules/messages-and-queries.md#messages) execution is typically priced, resulting in a `fee` (`fees = gas * gas-prices`). `fees` generally have to be paid by the sender of the `message`. Note that the Cosmos SDK does not enforce `gas` pricing by default, as there may be other ways to prevent spam (e.g. bandwidth schemes). Still, most applications will implement `fee` mechanisms to prevent spam. This is done via the [`AnteHandler`](#antehandler). ## Gas Meter @@ -42,7 +42,7 @@ By default, the Cosmos SDK makes use of two different gas meters, the [main gas ### Main Gas Meter -`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`GasTxMiddleware` middleware](#middleware), so that it can track gas consumption per-transaction. +`ctx.GasMeter()` is the main gas meter of the application. The main gas meter is initialized in `BeginBlock` via `setDeliverState`, and then tracks gas consumption during execution sequences that lead to state-transitions, i.e. those originally triggered by [`BeginBlock`](../core/baseapp.md#beginblock), [`DeliverTx`](../core/baseapp.md#delivertx) and [`EndBlock`](../core/baseapp.md#endblock). At the beginning of each `DeliverTx`, the main gas meter **must be set to 0** in the [`AnteHandler`](#antehandler), so that it can track gas consumption per-transaction. Gas consumption can be done manually, generally by the module developer in the [`BeginBlocker`, `EndBlocker`](../building-modules/beginblock-endblock.md) or [`Msg` service](../building-modules/msg-services.md), but most of the time it is done automatically whenever there is a read or write to the store. This automatic gas consumption logic is implemented in a special store called [`GasKv`](../core/store.md#gaskv-store). @@ -61,22 +61,22 @@ ctx.BlockGasMeter().ConsumeGas( ) ``` -## Middleware +## AnteHandler -The `GasTxMiddleware` is run for every transaction during `CheckTx` and `DeliverTx`, before a Protobuf `Msg` service method for each `sdk.Msg` in the transaction. +The `AnteHandler` is run for every transaction during `CheckTx` and `DeliverTx`, before a Protobuf `Msg` service method for each `sdk.Msg` in the transaction. -The `GasTxMiddleware` is not implemented in the core Cosmos SDK but in a module. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth/middleware). Here is what the `middleware` is intended to do in a normal Cosmos SDK application: +The anteHandler is not implemented in the core Cosmos SDK but in a module. That said, most applications today use the default implementation defined in the [`auth` module](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth). Here is what the `anteHandler` is intended to do in a normal Cosmos SDK application: -* Verify that the transactions are of the correct type. Transaction types are defined in the module that implements the `middleware`, and they follow the transaction interface: - +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/types/tx_msg.go#L38-L46 +* Verify that the transactions are of the correct type. Transaction types are defined in the module that implements the `anteHandler`, and they follow the transaction interface: + +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/types/tx_msg.go#L38-L46 This enables developers to play with various types for the transaction of their application. In the default `auth` module, the default transaction type is `Tx`: - +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/tx/v1beta1/tx.proto#L13-L26 -* Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified by a `middleware`. + +++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/tx/v1beta1/tx.proto#L13-L26 +* Verify signatures for each [`message`](../building-modules/messages-and-queries.md#messages) contained in the transaction. Each `message` should be signed by one or multiple sender(s), and these signatures must be verified in the `anteHandler`. * During `CheckTx`, verify that the gas prices provided with the transaction is greater than the local `min-gas-prices` (as a reminder, gas-prices can be deducted from the following equation: `fees = gas * gas-prices`). `min-gas-prices` is a parameter local to each full-node and used during `CheckTx` to discard transactions that do not provide a minimum amount of fees. This ensures that the mempool cannot be spammed with garbage transactions. * Verify that the sender of the transaction has enough funds to cover for the `fees`. When the end-user generates a transaction, they must indicate 2 of the 3 following parameters (the third one being implicit): `fees`, `gas` and `gas-prices`. This signals how much they are willing to pay for nodes to execute their transaction. The provided `gas` value is stored in a parameter called `GasWanted` for later use. -* Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is crucial**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx.GasMeter` is set by the middleware each time `DeliverTx` is called). +* Set `newCtx.GasMeter` to 0, with a limit of `GasWanted`. **This step is crucial**, as it not only makes sure the transaction cannot consume infinite gas, but also that `ctx.GasMeter` is reset in-between each `DeliverTx` (`ctx` is set to `newCtx` after `anteHandler` is run, and the `anteHandler` is run each time `DeliverTx` is called). -As explained above, the middleware returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. +As explained above, the `anteHandler` returns a maximum limit of `gas` the transaction can consume during execution called `GasWanted`. The actual amount consumed in the end is denominated `GasUsed`, and we must therefore have `GasUsed =< GasWanted`. Both `GasWanted` and `GasUsed` are relayed to the underlying consensus engine when [`DeliverTx`](../core/baseapp.md#delivertx) returns. ## Next {hide} diff --git a/docs/basics/tx-lifecycle.md b/docs/basics/tx-lifecycle.md index 024a26b97dd2..efb59e1a00a2 100644 --- a/docs/basics/tx-lifecycle.md +++ b/docs/basics/tx-lifecycle.md @@ -79,7 +79,7 @@ through several steps, beginning with decoding `Tx`. ### Decoding -When `Tx` is received by the application from the underlying consensus engine (e.g. Tendermint), it is still in its [encoded](../core/encoding.md) `[]byte` form and needs to be unmarshaled in order to be processed. Then, the transaction is passed to the middlewares defined in `tx.Handler`. The middlewares will perform additional checks defined in their own `CheckTx`, meaning that they will run all checks but exit before executing messages and writing state changes. +When `Tx` is received by the application from the underlying consensus engine (e.g. Tendermint), it is still in its [encoded](../core/encoding.md) `[]byte` form and needs to be unmarshaled in order to be processed. Then, the [`runTx`](../core/baseapp.md#runtx-antehandler-runmsgs-posthandler) function is called to run in `runTxModeCheck` mode, meaning the function will run all checks but exit before executing messages and writing state changes. ### ValidateBasic @@ -96,13 +96,13 @@ Example, if the message is to send coins from one address to another, `ValidateB See also [Msg Service Validation](../building-modules/msg-services.md#Validation). -### Middlewares +### AnteHandler -Middlewares implements the `TxHandler` interface and are defined by `tx.Handler` in `BaseApp`. This architecture allows running the middlewares logic in the `CheckTx` and `DeliverTx` phases. Technically, they are optional, but in practice, they are very often present to perform signature verification, gas calculation, fee deduction and other core operations related to blockchain transactions. +After the ValidateBasic checks, the `AnteHandler`s are run. Technically, they are optional, but in practice, they are very often present to perform signature verification, gas calculation, fee deduction and other core operations related to blockchain transactions. -A copy of the cached context is provided to the middleware, which performs limited checks specified for the transaction type. Using a copy allows the Middleware to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails. +A copy of the cached context is provided to the `AnteHandler`, which performs limited checks specified for the transaction type. Using a copy allows the `AnteHandler` to do stateful checks for `Tx` without modifying the last committed state, and revert back to the original if the execution fails. -For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth/spec) middlewares can check and increment sequence numbers, check signatures and account numbers, and deduct fees from the first signer of the transaction - all state changes are made using the `checkState`. +For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth/spec) module `AnteHandler` checks and increments sequence numbers, checks signatures and account numbers, and deducts fees from the first signer of the transaction - all state changes are made using the `checkState`. ### Gas @@ -201,20 +201,21 @@ Instead of using their `checkState`, full-nodes use `deliverState`: * **Decoding:** Since `DeliverTx` is an ABCI call, `Tx` is received in the encoded `[]byte` form. Nodes first unmarshal the transaction, using the [`TxConfig`](./app-anatomy#register-codec) defined in the app, then call `runTx` in `runTxModeDeliver`, which is very similar to `CheckTx` but also executes and writes state changes. -* **Checks:** Full-nodes call `validateBasicMsgs` and the `DeliverTx` from the middleware again. This second check - happens because they may not have seen the same transactions during the addition to Mempool stage\ +* **Checks and AnteHandler:** Full-nodes call `validateBasicMsgs` and `AnteHandler` again. This second check + happens because they may not have seen the same transactions during the addition to Mempool stage and a malicious proposer may have included invalid ones. One difference here is that the - middleware will not compare `gas-prices` to the node's `min-gas-prices` since that value is local + `AnteHandler` will not compare `gas-prices` to the node's `min-gas-prices` since that value is local to each node - differing values across nodes would yield nondeterministic results. -* **`RunMsgsTxHandler`:** While `CheckTx` would have exited, `DeliverTx` continues to run - [`RunMsgsTxHandler`](../core/baseapp.md#middlewares) to fully execute each `Msg` within the transaction. +* **`MsgServiceRouter`:** While `CheckTx` would have exited, `DeliverTx` continues to run + [`runMsgs`](../core/baseapp.md#runtx-antehandler-runmsgs-posthandler) to fully execute each `Msg` within the transaction. Since the transaction may have messages from different modules, `BaseApp` needs to know which module - to find the appropriate handler. This is achieved using `RunMsgsTxHandler`'s `MsgServiceRouter` so that it can be processed by the module's Protobuf [`Msg` service](../building-modules/msg-services.md). + to find the appropriate handler. This is achieved using `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's Protobuf [`Msg` service](../building-modules/msg-services.md). For `LegacyMsg` routing, the `Route` function is called via the [module manager](../building-modules/module-manager.md) to retrieve the route name and find the legacy [`Handler`](../building-modules/msg-services.md#handler-type) within the module. + +* **`Msg` service:** Protobuf `Msg` service is responsible for executing each message in the `Tx` and causes state transitions to persist in `deliverTxState`. -* **`Msg` service:** a Protobuf `Msg` service is responsible for executing each - message in the `Tx` and causes state transitions to persist in `deliverTxState`. +* **PostHandlers:** [`PostHandler`](../core/baseapp.md#posthandler)s run after the execution of the message. If they fail, the state change of `runMsgs`, as well of `PostHandlers` are both reverted. * **Gas:** While a `Tx` is being delivered, a `GasMeter` is used to keep track of how much gas is being used; if execution completes, `GasUsed` is set and returned in the diff --git a/docs/building-modules/msg-services.md b/docs/building-modules/msg-services.md index 82f4e44e6783..f28adab4ec87 100644 --- a/docs/building-modules/msg-services.md +++ b/docs/building-modules/msg-services.md @@ -23,11 +23,11 @@ Protobuf generates a `MsgServer` interface based on a definition of `Msg` servic When possible, the existing module's [`Keeper`](keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/bank/keeper/msg_server.go#L14:L16 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/bank/keeper/msg_server.go#L14-L16 `msgServer` methods can retrieve the `sdk.Context` from the `context.Context` parameter method using the `sdk.UnwrapSDKContext`: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/bank/keeper/msg_server.go#L27-L28 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/bank/keeper/msg_server.go#L27-L27 `sdk.Msg` processing usually follows these 3 steps: diff --git a/docs/core/README.md b/docs/core/README.md index ef83bfbbc0fb..a6853b41802a 100644 --- a/docs/core/README.md +++ b/docs/core/README.md @@ -11,15 +11,15 @@ This repository contains reference documentation on the core concepts of the Cos 1. [`BaseApp`](./baseapp.md) 2. [Transaction](./transactions.md) 3. [Context](./context.md) -4. [CheckTx and DeliverTx middlewares](./middleware.md) -5. [Node Client](./node.md) -6. [Store](./store.md) -7. [Encoding](./encoding.md) -8. [gRPC, REST and Tendermint Endpoints](./grpc_rest.md) -9. [Command-Line Interface](./cli.md) -10. [Events](./events.md) -11. [Telemetry](./telemetry.md) -12. [Object-Capabilities](./ocap.md) +4. [Node Client](./node.md) +5. [Store](./store.md) +6. [Encoding](./encoding.md) +7. [gRPC, REST and Tendermint Endpoints](./grpc_rest.md) +8. [Command-Line Interface](./cli.md) +9. [Events](./events.md) +10. [Telemetry](./telemetry.md) +11. [Object-Capabilities](./ocap.md) +12. [RunTx recovery middleware](./runtx_middleware.md) 13. [Simulation](./simulation.md) 14. [Protobuf documentation](./proto-docs.md) 15. [In-Place Store Migrations](./upgrade.md) diff --git a/docs/core/baseapp.md b/docs/core/baseapp.md index 6b1c47c37dce..5d61f137428c 100644 --- a/docs/core/baseapp.md +++ b/docs/core/baseapp.md @@ -45,7 +45,7 @@ management logic. The `BaseApp` type holds many important parameters for any Cosmos SDK based application. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/baseapp/baseapp.go#L44-L131 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/baseapp/baseapp.go#L45-L137 Let us go through the most important components. @@ -60,14 +60,18 @@ First, the important parameters that are initialized during the bootstrapping of The `CommitMultiStore` is a multi-store, meaning a store of stores. Each module of the application uses one or multiple `KVStores` in the multi-store to persist their subset of the state. * Database: The `db` is used by the `CommitMultiStore` to handle data persistence. +* [`Msg` Service Router](#msg-service-router): The `msgServiceRouter` facilitates the routing of `sdk.Msg` requests to the appropriate + module `Msg` service for processing. Here a `sdk.Msg` refers to the transaction component that needs to be + processed by a service in order to update the application state, and not to ABCI message which implements + the interface between the application and the underlying consensus engine. * [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://godoc.org/github.com/cosmos/cosmos-sdk/types#TxDecoder): It is used to decode raw transaction bytes relayed by the underlying Tendermint engine. * [`ParamStore`](#paramstore): The parameter store used to get and set application consensus parameters. -* [`TxHandler`](#middlewares): This handler is used to set middlewares. Middlewares can, for instace, handle signature verification, - fee payment, and other pre-message execution checks when a transaction is received. It's executed during +* [`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 [`CheckTx/RecheckTx`](#checktx) and [`DeliverTx`](#delivertx). * [`InitChainer`](../basics/app-anatomy.md#initchainer), [`BeginBlocker` and `EndBlocker`](../basics/app-anatomy.md#beginblocker-and-endblocker): These are @@ -88,7 +92,7 @@ Finally, a few more important parameters: punishing absent validators. * `minGasPrices`: This parameter defines the minimum gas prices accepted by the node. This is a **local** parameter, meaning each full-node can set a different `minGasPrices`. It is used in the - `TxHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction + `AnteHandler` during [`CheckTx`](#checktx), mainly as a spam protection mechanism. The transaction enters the [mempool](https://docs.tendermint.com/master/tendermint-core/mempool/) only if the gas prices of the transaction are greater than one of the minimum gas price in `minGasPrices` (e.g. if `minGasPrices == 1uatom,1photon`, the `gas-price` of the transaction must be @@ -138,10 +142,11 @@ 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 wired middlewares `CheckTx` and verify a service router -exists for every message in the transaction. Note, that if a middleware's `CheckTx` fails, -the state transitions won't be reflected in the `checkState` -- i.e. `checkState` is only updated on -success. +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) @@ -159,7 +164,7 @@ The state flow for `DeliverTx` is nearly identical to `CheckTx` except state tra the `deliverState` and messages in a transaction are executed. Similarly to `CheckTx`, state transitions occur on a doubly branched state -- `deliverState`. Successful message execution results in writes being committed to `deliverState`. Note, if message execution fails, state transitions from -the middlewares are persisted. +the AnteHandler are persisted. ![DeliverTx](./baseapp_state-deliver_tx.png) @@ -182,13 +187,21 @@ on-chain governance. ## Service Routers -When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `BaseApp`, with `queryRouter` for queries and `grpcQueryRouter` for gRPC queries. +When messages and queries are received by the application, they must be routed to the appropriate module in order to be processed. Routing is done via `BaseApp`, which holds a `msgServiceRouter` for messages, and a `grpcQueryRouter` for queries. + +### `Msg` Service Router + +[`sdk.Msg`s](#../building-modules/messages-and-queries.md#messages) need to be routed after they are extracted from transactions, which are sent from the underlying Tendermint engine via the [`CheckTx`](#checktx) and [`DeliverTx`](#delivertx) 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.40.0-rc3/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.40.0-rc3/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 application's `msgServiceRouter` is initialized with all the routes using the application's [module manager](../building-modules/module-manager.md#manager) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#constructor-function). ### gRPC Query Router -[`Queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [`Query` service](../building-modules/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 Tendermint RPC endpoint. +Similar to `sdk.Msg`s, [`queries`](../building-modules/messages-and-queries.md#queries) need to be routed to the appropriate module's [`Query` service](../building-modules/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 Tendermint RPC endpoint. -The `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../building-modules/module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). +Just like the `msgServiceRouter`, the `grpcQueryRouter` is initialized with all the query routes using the application's [module manager](../building-modules/module-manager.md) (via the `RegisterServices` method), which itself is initialized with all the application's modules in the application's [constructor](../basics/app-anatomy.md#app-constructor). ## Main ABCI Messages @@ -223,17 +236,18 @@ to do the following checks: 3. Perform non-module related _stateful_ checks on the [account](../basics/accounts.md). This step is mainly about checking that the `sdk.Msg` signatures are valid, that enough fees are provided and that the sending account has enough funds to pay for said fees. Note that no precise [`gas`](../basics/gas-fees.md) counting occurs here, - as `sdk.Msg`s are not processed. Usually, the [`middleware`](../basics/gas-fees.md#middleware) will check that the `gas` provided + as `sdk.Msg`s are not processed. Usually, the [`AnteHandler`](../basics/gas-fees.md#antehandler) will check that the `gas` provided with the transaction is superior to a minimum reference gas amount based on the raw transaction size, in order to avoid spam with transactions that provide 0 gas. `CheckTx` does **not** process `sdk.Msg`s - they only need to be processed when the canonical state need to be updated, which happens during `DeliverTx`. -Steps 2. and 3. are performed by the [`middlewares`](../basics/gas-fees.md#middleware)' `CheckTx()`. -During each step of `CheckTx()`, a special [volatile state](#state-updates) called `checkState` is updated. -This state is used to keep track of the temporary changes triggered by the `CheckTx()` calls of each transaction -without modifying the [main canonical state](#main-state) . For example, when a transaction goes through `CheckTx()`, -the transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is +Steps 2. and 3. are performed by the [`AnteHandler`](../basics/gas-fees.md#antehandler) in the [`RunTx()`](#runtx-antehandler-and-runmsgs) +function, which `CheckTx()` calls with the `runTxModeCheck` mode. During each step of `CheckTx()`, a +special [volatile state](#state-updates) called `checkState` is updated. This state is used to keep +track of the temporary changes triggered by the `CheckTx()` calls of each transaction without modifying +the [main canonical state](#main-state). For example, when a transaction goes through `CheckTx()`, the +transaction's fees are deducted from the sender's account in `checkState`. If a second transaction is received from the same account before the first is processed, and the account has consumed all its funds in `checkState` during the first transaction, the second transaction will fail `CheckTx`() and be rejected. In any case, the sender's account will not actually pay the fees until the transaction @@ -270,12 +284,12 @@ Before the first transaction of a given block is processed, a [volatile state](# `DeliverTx` performs the **exact same steps as `CheckTx`**, with a little caveat at step 3 and the addition of a fifth step: -1. The `GasTxMiddleware` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. +1. The `AnteHandler` does **not** check that the transaction's `gas-prices` is sufficient. That is because the `min-gas-prices` value `gas-prices` is checked against is local to the node, and therefore what is enough for one full-node might not be for another. This means that the proposer can potentially include transactions for free, although they are not incentivised to do so, as they earn a bonus on the total fee of the block they propose. 2. For each `sdk.Msg` in the transaction, route to the appropriate module's Protobuf [`Msg` service](../building-modules/msg-services.md). Additional _stateful_ checks are performed, and the branched multistore held in `deliverState`'s `context` is updated by the module's `keeper`. If the `Msg` service returns successfully, the branched multistore held in `context` is written to `deliverState` `CacheMultiStore`. 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: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/store/types/gas.go#L230-L241 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/store/types/gas.go#L230-L241 At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0` and `DeliverTx` fails. @@ -290,32 +304,56 @@ At any point, if `GasConsumed > GasWanted`, the function returns with `Code != 0 * `Events ([]cmn.KVPair)`: Key-Value tags for filtering and indexing transactions (eg. by account). See [`event`s](./events.md) for more. * `Codespace (string)`: Namespace for the Code. -## Middlewares +## RunTx, AnteHandler, RunMsgs, PostHandler + +### RunTx + +`RunTx` is called from `CheckTx`/`DeliverTx` to handle the transaction, with `runTxModeCheck` or `runTxModeDeliver` as parameter to differentiate between the two modes of execution. Note that when `RunTx` receives a transaction, it has already been decoded. + +The first thing `RunTx` does upon being called is to retrieve the `context`'s `CacheMultiStore` by calling the `getContextForTx()` function with the appropriate mode (either `runTxModeCheck` or `runTxModeDeliver`). This `CacheMultiStore` is a branch of the main store, with cache functionality (for query requests), instantiated during `BeginBlock` for `DeliverTx` and during the `Commit` of the previous block for `CheckTx`. After that, two `defer func()` are called for [`gas`](../basics/gas-fees.md) management. They are executed when `runTx` returns and make sure `gas` is actually consumed, and will throw errors, if any. + +After that, `RunTx()` calls `ValidateBasic()` on each `sdk.Msg`in the `Tx`, which runs preliminary _stateless_ validity checks. If any `sdk.Msg` fails to pass `ValidateBasic()`, `RunTx()` returns with an error. -Middlewares implement the `tx.Handler` interface. They are called within BaseApp `CheckTx` and `DeliverTx`, allowing to run custom logic before or after the transaction is processed. They are primarily used to authenticate the transaction before the transaction's internal messages are processed, but also to perform additional checks on the transaction itself. +Then, the [`anteHandler`](#antehandler) of the application is run (if it exists). In preparation of this step, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are branched using the `cacheTxContext()` function. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/types/tx/middleware.go#L62:L68 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/baseapp/baseapp.go#L651-L657 -Middlewares are theoretically optional, but still a very important component of public blockchain networks. They have 3 primary purposes: +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](./ocap.md) of the Cosmos SDK. + +Finally, the [`RunMsgs()`](#runmsgs) function is called to process the `sdk.Msg`s in the `Tx`. In preparation of this step, just like with the `anteHandler`, both the `checkState`/`deliverState`'s `context` and `context`'s `CacheMultiStore` are branched using the `cacheTxContext()` function. + +### AnteHandler + +The `AnteHandler` is a special handler that implements the `AnteHandler` interface and is used to authenticate the transaction before the transaction's internal messages are processed. + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/types/handler.go#L6-L8 + +The `AnteHandler` is theoretically optional, but still a very important component of public blockchain networks. It serves 3 primary purposes: * Be a primary line of defense against spam and second line of defense (the first one being the mempool) against transaction replay with fees deduction and [`sequence`](./transactions.md#transaction-generation) checking. * Perform preliminary _stateful_ validity checks like ensuring signatures are valid or that the sender has enough funds to pay for fees. * Play a role in the incentivisation of stakeholders via the collection of transaction fees. -`BaseApp` holds a `txHandler` as parameter that is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `middlewares` are the [`auth` module middlewares](https://github.com/cosmos/cosmos-sdk/blob/main/x/auth/middleware). +`BaseApp` holds an `anteHandler` as parameter that is initialized in the [application's constructor](../basics/app-anatomy.md#application-constructor). The most widely used `anteHandler` is the [`auth` module](https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/x/auth/ante/ante.go). + +Click [here](../basics/gas-fees.md#antehandler) for more on the `anteHandler`. + +### RunMsgs + +`RunMsgs` is called from `RunTx` with `runTxModeCheck` as parameter to check the existence of a route for each message the transaction, and with `runTxModeDeliver` to actually process the `sdk.Msg`s. -`NewDefaultTxHandler` groups a number a `middlewares` that are commonly used: +First, it retrieves the `sdk.Msg`'s fully-qualified type name, by checking the `type_url` of the Protobuf `Any` representing the `sdk.Msg`. Then, using the application's [`msgServiceRouter`](#msg-service-router), it checks for the existence of `Msg` service method related to that `type_url`. At this point, if `mode == runTxModeCheck`, `RunMsgs` returns. Otherwise, if `mode == runTxModeDeliver`, the [`Msg` service](../building-modules/msg-services.md) RPC is executed, before `RunMsgs` returns. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/auth/middleware/middleware.go#L89:L130 +### PostHandler -Click [here](../basics/gas-fees.md#middleware) for more on these `middlewares`. +_PostHandler_ are like `AnteHandler` (they share the same signature), but they execute after [`RunMsgs`](#runmsgs). -### RunMsgsTxHandler +Like `AnteHandler`s, `PostHandler`s are theoretically optional, one use case for `PostHandler`s is transaction tips (enabled by default in simapp). +Other use cases like unused gas refund can also be enabled by `PostHandler`s. -`RunMsgsTxHandler` is a middleware that runs the `sdk.Msg`s in the transaction. -When being called from `DeliverTx` or `SimulateTx`, it retrieves the `sdk.Msg`'s fully-qualified type name, by checking the `type_url` of the Protobuf `Any` representing the `sdk.Msg`. Then, using its [`msgServiceRouter`](#msg-service-router), it checks for the existence of `Msg` service method related to that `type_url`. At this point the [`Msg` service](../building-modules/msg-services.md) RPC is executed, before returning. ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/auth/posthandler/post.go#L14:L27 -Note: When its `CheckTx` method is called, the `RunMsgsTxHandler` does not do anything as messages are not run during `CheckTx`. +Note, when `PostHandler`s fail, the state from `runMsgs` is also reverted, effectively making the transaction fail. ## Other ABCI Messages diff --git a/docs/core/baseapp_transaction-middleware.png b/docs/core/baseapp_transaction-middleware.png deleted file mode 100644 index 76db2a6b1475..000000000000 Binary files a/docs/core/baseapp_transaction-middleware.png and /dev/null differ diff --git a/docs/core/cli.md b/docs/core/cli.md index 2caca1103d37..9e11d9da0c4d 100644 --- a/docs/core/cli.md +++ b/docs/core/cli.md @@ -1,5 +1,5 @@ # Command-Line Interface diff --git a/docs/core/context.md b/docs/core/context.md index a1e912797b8c..39344a9f68d7 100644 --- a/docs/core/context.md +++ b/docs/core/context.md @@ -72,9 +72,29 @@ goes wrong. The pattern of usage for a Context is as follows: needs to be done - the branch `ctx` is simply discarded. If successful, the changes made to the `CacheMultiStore` can be committed to the original `ctx.ms` via `Write()`. -For example, here is a snippet from the [`CustomTxHandlerMiddleware`](https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/baseapp/custom_txhandler_test.go#L23) used in tests: +For example, here is a snippet from the [`runTx`](./baseapp.md#runtx-antehandler-runmsgs-posthandler) function in [`baseapp`](./baseapp.md): -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/baseapp/custom_txhandler_test.go#L62:L97 +```go +runMsgCtx, msCache := app.cacheTxContext(ctx, txBytes) +result = app.runMsgs(runMsgCtx, msgs, mode) +result.GasWanted = gasWanted +if mode != runTxModeDeliver { + return result +} +if result.IsOK() { + msCache.Write() +} +``` + +Here is the process: + +1. Prior to calling `runMsgs` on the message(s) in the transaction, it uses `app.cacheTxContext()` + to branch and cache the context and multistore. +2. `runMsgCtx` - the context with branched store, is used in `runMsgs` to return a result. +3. If the process is running in [`checkTxMode`](./baseapp.md#checktx), there is no need to write the + changes - the result is returned immediately. +4. If the process is running in [`deliverTxMode`](./baseapp.md#delivertx) and the result indicates + a successful run over all the messages, the branched multistore is written back to the original. ## Next {hide} diff --git a/docs/core/encoding.md b/docs/core/encoding.md index dea5ce105b65..ed90202b3abe 100644 --- a/docs/core/encoding.md +++ b/docs/core/encoding.md @@ -1,5 +1,5 @@ # Encoding diff --git a/docs/core/events.md b/docs/core/events.md index 62362a6ded99..616f9c6541e3 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -1,5 +1,5 @@ # Events diff --git a/docs/core/grpc_rest.md b/docs/core/grpc_rest.md index 527757534620..f37c1f397a4a 100644 --- a/docs/core/grpc_rest.md +++ b/docs/core/grpc_rest.md @@ -1,5 +1,5 @@ # gRPC, REST, and Tendermint Endpoints diff --git a/docs/core/middleware.md b/docs/core/middleware.md deleted file mode 100644 index f7ea5dd8df10..000000000000 --- a/docs/core/middleware.md +++ /dev/null @@ -1,153 +0,0 @@ - - -# 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} -* [Transactions](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 the previous notion of `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: - -![Composing](./baseapp_transaction-middleware.png) - -```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 middleware 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.45.3/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 | diff --git a/docs/core/node.md b/docs/core/node.md index 67497e9f58d7..a4b8c3bd5f0f 100644 --- a/docs/core/node.md +++ b/docs/core/node.md @@ -1,5 +1,5 @@ # Node Client (Daemon) diff --git a/docs/core/ocap.md b/docs/core/ocap.md index dd3d40d7ea52..a365fd106ec2 100644 --- a/docs/core/ocap.md +++ b/docs/core/ocap.md @@ -1,5 +1,5 @@ # Object-Capability Model diff --git a/docs/core/runtx_middleware.md b/docs/core/runtx_middleware.md new file mode 100644 index 000000000000..8b39f127ec9a --- /dev/null +++ b/docs/core/runtx_middleware.md @@ -0,0 +1,69 @@ + + +# RunTx recovery middleware + +`BaseApp.runTx()` function handles Go panics that might occur during transactions execution, for example, keeper has faced an invalid state and paniced. +Depending on the panic type different handler is used, for instance the default one prints an error log message. +Recovery middleware is used to add custom panic recovery for Cosmos SDK application developers. + +More context can found in the corresponding [ADR-022](../architecture/adr-022-custom-panic-handling.md) and the implementation in [recovery.go](https://github.com/cosmos/cosmos-sdk/tree/v0.46.0-rc1/baseapp/recovery.go). + +## Interface + ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/baseapp/recovery.go#L11-L14 + +`recoveryObj` is a return value for `recover()` function from the `buildin` Go package. + +**Contract:** + +* RecoveryHandler returns `nil` if `recoveryObj` wasn't handled and should be passed to the next recovery middleware; +* RecoveryHandler returns a non-nil `error` if `recoveryObj` was handled; + +## Custom RecoveryHandler register + +`BaseApp.AddRunTxRecoveryHandler(handlers ...RecoveryHandler)` + +BaseApp method adds recovery middleware to the default recovery chain. + +## Example + +Lets assume we want to emit the "Consensus failure" chain state if some particular error occurred. + +We have a module keeper that panics: + +```go +func (k FooKeeper) Do(obj interface{}) { + if obj == nil { + // that shouldn't happen, we need to crash the app + err := sdkErrors.Wrap(fooTypes.InternalError, "obj is nil") + panic(err) + } +} +``` + +By default that panic would be recovered and an error message will be printed to log. To override that behaviour we should register a custom RecoveryHandler: + +```go +// Cosmos SDK application constructor +customHandler := func(recoveryObj interface{}) error { + err, ok := recoveryObj.(error) + if !ok { + return nil + } + + if fooTypes.InternalError.Is(err) { + panic(fmt.Errorf("FooKeeper did panic with error: %w", err)) + } + + return nil +} + +baseApp := baseapp.NewBaseApp(...) +baseApp.AddRunTxRecoveryHandler(customHandler) +``` + +## Next {hide} + +Learn about the [IBC](./../ibc/README.md) protocol {hide} diff --git a/docs/core/store.md b/docs/core/store.md index 3a07815620de..e7ff13e68765 100644 --- a/docs/core/store.md +++ b/docs/core/store.md @@ -1,5 +1,5 @@ # Store diff --git a/docs/core/telemetry.md b/docs/core/telemetry.md index 3c312c7fa322..d34ad51ec1d2 100644 --- a/docs/core/telemetry.md +++ b/docs/core/telemetry.md @@ -1,5 +1,5 @@ # Telemetry diff --git a/docs/core/transactions.md b/docs/core/transactions.md index b8b7ec774107..66f3cd9a7efa 100644 --- a/docs/core/transactions.md +++ b/docs/core/transactions.md @@ -20,12 +20,12 @@ When users want to interact with an application and make state changes (e.g. sen Transaction objects are Cosmos SDK types that implement the `Tx` interface -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/types/tx_msg.go#L38-L46 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/types/tx_msg.go#L38-L46 It contains the following methods: * **GetMsgs:** unwraps the transaction and returns a list of contained `sdk.Msg`s - one transaction may have one or multiple messages, which are defined by module developers. -* **ValidateBasic:** lightweight, [_stateless_](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth) module's `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from `sdk.Msg` [`ValidateBasic`](../basics/tx-lifecycle.md#ValidateBasic) methods, which perform basic validity checks on messages only. When using [`ValidateBasicMiddleware`](https://github.com/cosmos/cosmos-sdk/blob/main/x/auth/spec/03_middlewares.md), `ValidateBasic` is called on each message, and then the middleware calls `ValidateBasic` for the transaction itself. +* **ValidateBasic:** lightweight, [_stateless_](../basics/tx-lifecycle.md#types-of-checks) checks used by ABCI messages [`CheckTx`](./baseapp.md#checktx) and [`DeliverTx`](./baseapp.md#delivertx) to make sure transactions are not invalid. For example, the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth) module's `ValidateBasic` function checks that its transactions are signed by the correct number of signers and that the fees do not exceed what the user's maximum. Note that this function is to be distinct from `sdk.Msg` [`ValidateBasic`](../basics/tx-lifecycle.md#ValidateBasic) methods, which perform basic validity checks on messages only. When [`runTx`](./baseapp.md#runtx) is checking a transaction created from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/main/x/auth/spec) module, it first runs `ValidateBasic` on each message, then runs the `auth` module AnteHandler which calls `ValidateBasic` for the transaction itself. As a developer, you should rarely manipulate `Tx` directly, as `Tx` is really an intermediate type used for transaction generation. Instead, developers should prefer the `TxBuilder` interface, which you can learn more about [below](#transaction-generation). @@ -53,7 +53,7 @@ The legacy implementation of the `Tx` interface is the `StdTx` struct from `x/au The document signed by all signers is `StdSignDoc`: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/auth/migrations/legacytx/stdsign.go#L38-L52 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/auth/migrations/legacytx/stdsign.go#L38-L52 which is encoded into bytes using Amino JSON. Once all signatures are gathered into `StdTx`, `StdTx` is serialized using Amino JSON, and these bytes are broadcasted over the network. @@ -66,7 +66,7 @@ The Cosmos SDK also provides a couple of other sign modes for particular use cas `SIGN_MODE_DIRECT_AUX` is a sign mode released in the Cosmos SDK v0.46 which targets transactions with multiple signers. Whereas `SIGN_MODE_DIRECT` expects each signer to sign over both `TxBody` and `AuthInfo` (which includes all other signers' signer infos, i.e. their account sequence, public key and mode info), `SIGN_MODE_DIRECT_AUX` allows N-1 signers to only sign over `TxBody` and _their own_ signer info. Morever, each auxiliary signer (i.e. a signer using `SIGN_MODE_DIRECT_AUX`) doesn't need to sign over the fees: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/tx/v1beta1/tx.proto#L67-L93 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/tx/v1beta1/tx.proto#L67-L93 The use case is a multi-signer transaction, where one of the signers is appointed to gather all signatures, broadcast the signature and pay for fees, and the others only care about the transaction body. This generally allows for a better multi-signing UX. If Alice, Bob and Charlie are part of a 3-signer transaction, then Alice and Bob can both use `SIGN_MODE_DIRECT_AUX` to sign over the `TxBody` and their own signer info (no need an additional step to gather other signers' ones, like in `SIGN_MODE_DIRECT`), without specifying a fee in their SignDoc. Charlie can then gather both signatures from Alice and Bob, and create the final transaction by appending a fee. Note that the fee payer of the transaction (in our case Charlie) must sign over the fees, so must use `SIGN_MODE_DIRECT` or `SIGN_MODE_LEGACY_AMINO_JSON`. diff --git a/docs/intro/sdk-app-architecture.md b/docs/intro/sdk-app-architecture.md index 2a6b52b2d9ec..7a111368338f 100644 --- a/docs/intro/sdk-app-architecture.md +++ b/docs/intro/sdk-app-architecture.md @@ -84,8 +84,8 @@ Note that **Tendermint only handles transaction bytes**. It has no knowledge of Here are the most important messages of the ABCI: -* `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. The [middlewares](../basics/gas-fees.md#middleware) `CheckTx` are used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://docs.tendermint.com/v0.34/tendermint-core/mempool.html#mempool) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. -* `DeliverTx`: When a [valid block](https://docs.tendermint.com/v0.34/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `middleware` executes its defined `DeliverTx`, along with the actual [`Msg` service](../building-modules/msg-services.md) RPC for each message in the transaction. +* `CheckTx`: When a transaction is received by Tendermint Core, it is passed to the application to check if a few basic requirements are met. `CheckTx` is used to protect the mempool of full-nodes against spam transactions. . A special handler called the [`AnteHandler`](../basics/gas-fees.md#antehandler) is used to execute a series of validation steps such as checking for sufficient fees and validating the signatures. If the checks are valid, the transaction is added to the [mempool](https://docs.tendermint.com/v0.34/tendermint-core/mempool.html#mempool) and relayed to peer nodes. Note that transactions are not processed (i.e. no modification of the state occurs) with `CheckTx` since they have not been included in a block yet. +* `DeliverTx`: When a [valid block](https://docs.tendermint.com/v0.34/spec/blockchain/blockchain.html#validation) is received by Tendermint Core, each transaction in the block is passed to the application via `DeliverTx` in order to be processed. It is during this stage that the state transitions occur. The `AnteHandler` executes again, along with the actual [`Msg` service](../building-modules/msg-services.md) RPC for each message in the transaction. * `BeginBlock`/`EndBlock`: These messages are executed at the beginning and the end of each block, whether the block contains transactions or not. It is useful to trigger automatic execution of logic. Proceed with caution though, as computationally expensive loops could slow down your blockchain, or even freeze it if the loop is infinite. Find a more detailed view of the ABCI methods from the [Tendermint docs](https://docs.tendermint.com/v0.35/introduction/what-is-tendermint.html#abci-overview). diff --git a/docs/intro/why-app-specific.md b/docs/intro/why-app-specific.md index e456edd1d070..91e84ce0c824 100644 --- a/docs/intro/why-app-specific.md +++ b/docs/intro/why-app-specific.md @@ -66,7 +66,7 @@ decentralized applications built with Smart Contracts are inherently capped in p Security is hard to quantify, and greatly varies from platform to platform. That said here are some important benefits an application-specific blockchain can bring in terms of security: -* Developers can choose proven programming languages like Golang when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. +* Developers can choose proven programming languages like Go when building their application-specific blockchains, as opposed to smart contract programming languages that are often more immature. * Developers are not constrained by the cryptographic functions made available by the underlying virtual-machines. They can use their own custom cryptography, and rely on well-audited crypto libraries. * Developers do not have to worry about potential bugs or exploitable mechanisms in the underlying virtual-machine, making it easier to reason about the security of the application. diff --git a/x/auth/spec/03_antehandlers.md b/x/auth/spec/03_antehandlers.md new file mode 100644 index 000000000000..b695d8597dc5 --- /dev/null +++ b/x/auth/spec/03_antehandlers.md @@ -0,0 +1,40 @@ + + +# AnteHandlers + +The `x/auth` module presently has no transaction handlers of its own, but does expose the special `AnteHandler`, used for performing basic validity checks on a transaction, such that it could be thrown out of the mempool. +The `AnteHandler` can be seen as a set of decorators that check transactions within the current context, per [ADR 010](https://github.com/cosmos/cosmos-sdk/blob/v0.43.0-alpha1/docs/architecture/adr-010-modular-antehandler.md). + +Note that the `AnteHandler` is called on both `CheckTx` and `DeliverTx`, as Tendermint proposers presently have the ability to include in their proposed block transactions which fail `CheckTx`. + +## Decorators + +The auth module provides `AnteDecorator`s that are recursively chained together into a single `AnteHandler` in the following order: + +* `SetUpContextDecorator`: Sets the `GasMeter` in the `Context` and wraps the next `AnteHandler` with a defer clause to recover from any downstream `OutOfGas` panics in the `AnteHandler` chain to return an error with information on gas provided and gas used. + +* `RejectExtensionOptionsDecorator`: Rejects all extension options which can optionally be included in protobuf transactions. + +* `MempoolFeeDecorator`: Checks if the `tx` fee is above local mempool `minFee` parameter during `CheckTx`. + +* `ValidateBasicDecorator`: Calls `tx.ValidateBasic` and returns any non-nil error. + +* `TxTimeoutHeightDecorator`: Check for a `tx` height timeout. + +* `ValidateMemoDecorator`: Validates `tx` memo with application parameters and returns any non-nil error. + +* `ConsumeGasTxSizeDecorator`: Consumes gas proportional to the `tx` size based on application parameters. + +* `DeductFeeDecorator`: Deducts the `FeeAmount` from first signer of the `tx`. If the `x/feegrant` module is enabled and a fee granter is set, it deducts fees from the fee granter account. + +* `SetPubKeyDecorator`: Sets the pubkey from a `tx`'s signers that does not already have its corresponding pubkey saved in the state machine and in the current context. + +* `ValidateSigCountDecorator`: Validates the number of signatures in `tx` based on app-parameters. + +* `SigGasConsumeDecorator`: Consumes parameter-defined amount of gas for each signature. This requires pubkeys to be set in context for all signers as part of `SetPubKeyDecorator`. + +* `SigVerificationDecorator`: Verifies all signatures are valid. This requires pubkeys to be set in context for all signers as part of `SetPubKeyDecorator`. + +* `IncrementSequenceDecorator`: Increments the account sequence for each signer to prevent replay attacks. diff --git a/x/auth/spec/03_middlewares.md b/x/auth/spec/03_middlewares.md deleted file mode 100644 index 3686430bdf6f..000000000000 --- a/x/auth/spec/03_middlewares.md +++ /dev/null @@ -1,38 +0,0 @@ - - -# Middlewares - -The `x/auth` module presently has no transaction handlers of its own, but does expose middlewares directly called from BaseApp's `CheckTx` and `DeliverTx`, which can be used for performing any operations on transactions, such as basic validity checks on a transaction such that it could be thrown out of the mempool, or routing the transactions to their `Msg` service to perform state transitions. -The middlewares can be seen as a set of decorators wrapped one on top of the other, that check transactions within the current context, per [ADR-045](https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/docs/architecture/adr-045-check-delivertx-middlewares.md). - -Note that the middlewares are called on both `CheckTx` and `DeliverTx`, as Tendermint proposers presently have the ability to include in their proposed block transactions which fail `CheckTx`. - -## List of Middleware - -The auth module provides: - -* one `tx.Handler`, called `RunMsgsTxHandler`, which routes each `sdk.Msg` from a transaction to the correct module `Msg` service, and runs each `sdk.Msg` to perform state transitions, -* a set of middlewares that are recursively chained together around the base `tx.Handler` in the following order (the first middleware's `pre`-hook is run first, and `post`-hook is run last): - - * `NewTxDecoderMiddleware`: Decodes the transaction bytes from ABCI `CheckTx` and `DeliverTx` into the SDK transaction type. This middleware is generally called first, as most middlewares logic rely on a decoded SDK transaction. - * `GasTxMiddleware`: Sets the `GasMeter` in the `Context`. - * `RecoveryTxMiddleware`: Wraps the next middleware with a defer clause to recover from any downstream panics in the middleware chain to return an error with information on gas provided and gas used. - * `RejectExtensionOptionsMiddleware`: Rejects all extension options which can optionally be included in protobuf transactions. - * `IndexEventsTxMiddleware`: Choose which events to index in Tendermint. Make sure no events are emitted outside of this middleware. - * `ValidateBasicMiddleware`: Calls `tx.ValidateBasic` and returns any non-nil error. - * `TxTimeoutHeightMiddleware`: Check for a `tx` height timeout. - * `ValidateMemoMiddleware`: Validates `tx` memo with application parameters and returns any non-nil error. - * `ConsumeGasTxSizeMiddleware`: Consumes gas proportional to the `tx` size based on application parameters. - * `DeductFeeMiddleware`: Deducts the `FeeAmount` from first signer of the `tx`. If the `x/feegrant` module is enabled and a fee granter is set, it deducts fees from the fee granter account. - * `SetPubKeyMiddleware`: Sets the pubkey from a `tx`'s signers that does not already have its corresponding pubkey saved in the state machine and in the current context. - * `ValidateSigCountMiddleware`: Validates the number of signatures in the `tx` based on app-parameters. - * `SigGasConsumeMiddleware`: Consumes parameter-defined amount of gas for each signature. This requires pubkeys to be set in context for all signers as part of `SetPubKeyMiddleware`. - * `SigVerificationMiddleware`: Verifies all signatures are valid. This requires pubkeys to be set in context for all signers as part of `SetPubKeyMiddleware`. - * `IncrementSequenceMiddleware`: Increments the account sequence for each signer to prevent replay attacks. - * `WithBranchedStore`: Creates a new MultiStore branch, discards downstream writes if the downstream returns error. - * `ConsumeBlockGasMiddleware`: Consume block gas. - * `TipMiddleware`: Transfer tips to the fee payer in transactions with tips. - -This default list of middlewares can be instantiated using the `NewDefaultTxHandler` function. If a chain wants to tweak the list of middlewares, they can create their own `NewTxHandler` function using the same template as `NewDefaultTxHandler`, and chain new middlewares in the `ComposeMiddleware` function. diff --git a/x/auth/spec/README.md b/x/auth/spec/README.md index 81d8ccd1c99b..1090bb6baa1e 100644 --- a/x/auth/spec/README.md +++ b/x/auth/spec/README.md @@ -24,7 +24,7 @@ This module is used in the Cosmos Hub. * [Gas & Fees](01_concepts.md#gas-&-fees) 2. **[State](02_state.md)** * [Accounts](02_state.md#accounts) -3. **[Middlewares](03_middlewares.md)** +3. **[AnteHandlers](03_antehandlers.md)** 4. **[Keepers](04_keepers.md)** * [Account Keeper](04_keepers.md#account-keeper) 5. **[Vesting](05_vesting.md)** diff --git a/x/authz/spec/02_state.md b/x/authz/spec/02_state.md index 4bd35e94f714..ac5df10220d0 100644 --- a/x/authz/spec/02_state.md +++ b/x/authz/spec/02_state.md @@ -12,7 +12,7 @@ Grants are identified by combining granter address (the address bytes of the gra The grant object encapsulates an `Authorization` type and an expiration timestamp: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/authz/v1beta1/authz.proto#L22-L30 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/authz/v1beta1/authz.proto#L22-L30 ## GrantQueue @@ -20,4 +20,4 @@ We are maintaining a queue for authz pruning, whenever a grant created an item w * GrantQueue: `0x02 | granter_address_len (1 byte) | granter_address_bytes | grantee_address_len (1 byte) | grantee_address_bytes | expiration_bytes -> ProtocalBuffer([]string{msgTypeUrls})` -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/authz/keeper/keys.go#L86-L102 \ No newline at end of file ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/authz/keeper/keys.go#L78-L93 diff --git a/x/feegrant/spec/01_concepts.md b/x/feegrant/spec/01_concepts.md index 06eccc936786..523ff3e94fe0 100644 --- a/x/feegrant/spec/01_concepts.md +++ b/x/feegrant/spec/01_concepts.md @@ -80,7 +80,7 @@ Example cmd: ## Granted Fee Deductions -Fees are deducted from grants in the `x/auth` middleware. To learn more about how middlewares work, read the [Auth Module Middlewares Guide](../../auth/spec/03_middlewares.md). +Fees are deducted from grants in the `x/auth` ante handler. To learn more about how ante handlers work, read the [Auth Module AnteHandlers Guide](../../auth/spec/03_antehandlers.md). ## Gas diff --git a/x/group/spec/01_concepts.md b/x/group/spec/01_concepts.md index de930a6c1ad9..07d42b10c784 100644 --- a/x/group/spec/01_concepts.md +++ b/x/group/spec/01_concepts.md @@ -46,7 +46,7 @@ and percentage. Any chain developer can extend upon these two, by creating custom decision policies, as long as they adhere to the `DecisionPolicy` interface: -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/x/group/types.go#L23-L37 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/x/group/types.go#L27-L41 ### Threshold decision policy @@ -96,11 +96,11 @@ Tallying is the counting of all votes on a proposal. It happens only once in the lifecycle of a proposal, but can be triggered by two factors, whichever happens first: -- either someone tries to execute the proposal (see next section), which can +* either someone tries to execute the proposal (see next section), which can happen on a `Msg/Exec` transaction, or a `Msg/{SubmitProposal,Vote}` transaction with the `Exec` field set. When a proposal execution is attempted, a tally is done first to make sure the proposal passes. -- or on `EndBlock` when the proposal's voting period end just passed. +* or on `EndBlock` when the proposal's voting period end just passed. If the tally result passes the decision policy's rules, then the proposal is marked as `PROPOSAL_STATUS_ACCEPTED`, or else it is marked as @@ -140,18 +140,18 @@ Proposals and votes are automatically pruned to avoid state bloat. Votes are pruned: -- either after a successful tally, i.e. a tally whose result passes the decision +* either after a successful tally, i.e. a tally whose result passes the decision policy's rules, which can be trigged by a `Msg/Exec` or a `Msg/{SubmitProposal,Vote}` with the `Exec` field set, -- or on `EndBlock` right after the proposal's voting period end. This applies to proposals with status `aborted` or `withdrawn` too. +* or on `EndBlock` right after the proposal's voting period end. This applies to proposals with status `aborted` or `withdrawn` too. whichever happens first. Proposals are pruned: -- on `EndBlock` whose proposal status is `withdrawn` or `aborted` on proposal's voting period end before tallying, -- and either after a successful proposal execution, -- or on `EndBlock` right after the proposal's `voting_period_end` + +* on `EndBlock` whose proposal status is `withdrawn` or `aborted` on proposal's voting period end before tallying, +* and either after a successful proposal execution, +* or on `EndBlock` right after the proposal's `voting_period_end` + `max_execution_period` (defined as an app-wide configuration) is passed, whichever happens first. diff --git a/x/group/spec/03_messages.md b/x/group/spec/03_messages.md index e6566ce802be..c0b9b0fd7381 100644 --- a/x/group/spec/03_messages.md +++ b/x/group/spec/03_messages.md @@ -11,32 +11,32 @@ A new group can be created with the `MsgCreateGroup`, which has an admin address The metadata has a maximum length that is chosen by the app developer, and passed into the group keeper as a config. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L65-L76 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L66-L78 It's expected to fail if -- metadata length is greater than `MaxMetadataLen` +* metadata length is greater than `MaxMetadataLen` config -- members are not correctly set (e.g. wrong address format, duplicates, or with 0 weight). +* members are not correctly set (e.g. wrong address format, duplicates, or with 0 weight). ## Msg/UpdateGroupMembers Group members can be updated with the `UpdateGroupMembers`. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L85-L98 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L87-L100 In the list of `MemberUpdates`, an existing member can be removed by setting its weight to 0. It's expected to fail if: -- the signer is not the admin of the group. -- for any one of the associated group policies, if its decision policy's `Validate()` method fails against the updated group. +* the signer is not the admin of the group. +* for any one of the associated group policies, if its decision policy's `Validate()` method fails against the updated group. ## Msg/UpdateGroupAdmin The `UpdateGroupAdmin` can be used to update a group admin. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L103-L115 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L105-L117 It's expected to fail if the signer is not the admin of the group. @@ -44,30 +44,30 @@ It's expected to fail if the signer is not the admin of the group. The `UpdateGroupMetadata` can be used to update a group metadata. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L120-L132 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L122-L134 It's expected to fail if: -- new metadata length is greater than `MaxMetadataLen` config. -- the signer is not the admin of the group. +* new metadata length is greater than `MaxMetadataLen` config. +* the signer is not the admin of the group. ## Msg/CreateGroupPolicy A new group policy can be created with the `MsgCreateGroupPolicy`, which has an admin address, a group id, a decision policy and some optional metadata. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L141-L158 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L143-L160 It's expected to fail if: -- the signer is not the admin of the group. -- metadata length is greater than `MaxMetadataLen` config. -- the decision policy's `Validate()` method doesn't pass against the group. +* the signer is not the admin of the group. +* metadata length is greater than `MaxMetadataLen` config. +* the decision policy's `Validate()` method doesn't pass against the group. ## Msg/CreateGroupWithPolicy A new group with policy can be created with the `MsgCreateGroupWithPolicy`, which has an admin address, a list of members, a decision policy, a `group_policy_as_admin` field to optionally set group and group policy admin with group policy address and some optional metadata for group and group policy. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L181-L202 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L183-L206 It's expected to fail for the same reasons as `Msg/CreateGroup` and `Msg/CreateGroupPolicy`. @@ -75,7 +75,7 @@ It's expected to fail for the same reasons as `Msg/CreateGroup` and `Msg/CreateG The `UpdateGroupPolicyAdmin` can be used to update a group policy admin. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L167-L179 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L169-L181 It's expected to fail if the signer is not the admin of the group policy. @@ -83,77 +83,77 @@ It's expected to fail if the signer is not the admin of the group policy. The `UpdateGroupPolicyDecisionPolicy` can be used to update a decision policy. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L217-L231 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L219-L235 It's expected to fail if: -- the signer is not the admin of the group policy. -- the new decision policy's `Validate()` method doesn't pass against the group. +* the signer is not the admin of the group policy. +* the new decision policy's `Validate()` method doesn't pass against the group. ## Msg/UpdateGroupPolicyMetadata The `UpdateGroupPolicyMetadata` can be used to update a group policy metadata. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L236-L248 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L240-L252 It's expected to fail if: -- new metadata length is greater than `MaxMetadataLen` config. -- the signer is not the admin of the group. +* new metadata length is greater than `MaxMetadataLen` config. +* the signer is not the admin of the group. ## Msg/SubmitProposal A new proposal can be created with the `MsgSubmitProposal`, which has a group policy account address, a list of proposers addresses, a list of messages to execute if the proposal is accepted and some optional metadata. An optional `Exec` value can be provided to try to execute the proposal immediately after proposal creation. Proposers signatures are considered as yes votes in this case. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L271-L294 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L275-L298 It's expected to fail if: -- metadata length is greater than `MaxMetadataLen` config. -- if any of the proposers is not a group member. +* metadata length is greater than `MaxMetadataLen` config. +* if any of the proposers is not a group member. ## Msg/WithdrawProposal A proposal can be withdrawn using `MsgWithdrawProposal` which has an `address` (can be either a proposer or the group policy admin) and a `proposal_id` (which has to be withdrawn). -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L303-L310 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L307-L316 It's expected to fail if: -- the signer is neither the group policy admin nor proposer of the proposal. -- the proposal is already closed or aborted. +* the signer is neither the group policy admin nor proposer of the proposal. +* the proposal is already closed or aborted. ## Msg/Vote A new vote can be created with the `MsgVote`, given a proposal id, a voter address, a choice (yes, no, veto or abstain) and some optional metadata. An optional `Exec` value can be provided to try to execute the proposal immediately after voting. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L315-L333 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L321-L339 It's expected to fail if: -- metadata length is greater than `MaxMetadataLen` config. -- the proposal is not in voting period anymore. +* metadata length is greater than `MaxMetadataLen` config. +* the proposal is not in voting period anymore. ## Msg/Exec A proposal can be executed with the `MsgExec`. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L338-L347 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L341-L353 The messages that are part of this proposal won't be executed if: -- the proposal has not been accepted by the group policy. -- the proposal has already been successfully executed. +* the proposal has not been accepted by the group policy. +* the proposal has already been successfully executed. ## Msg/LeaveGroup The `MsgLeaveGroup` allows group member to leave a group. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/group/v1/tx.proto#L352-L361 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/group/v1/tx.proto#L362-L370 It's expected to fail if: -- the group member is not part of the group. -- for any one of the associated group policies, if its decision policy's `Validate()` method fails against the updated group. +* the group member is not part of the group. +* for any one of the associated group policies, if its decision policy's `Validate()` method fails against the updated group. diff --git a/x/upgrade/spec/01_concepts.md b/x/upgrade/spec/01_concepts.md index d6ccbb7eaadd..10ff5ad3611d 100644 --- a/x/upgrade/spec/01_concepts.md +++ b/x/upgrade/spec/01_concepts.md @@ -82,7 +82,7 @@ This proposal prescribes to the standard governance process. If the proposal pas the `Plan`, which targets a specific `Handler`, is persisted and scheduled. The upgrade can be delayed or hastened by updating the `Plan.Height` in a new proposal. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/upgrade/v1beta1/tx.proto#L24-L35 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L24-L36 ### Cancelling Upgrade Proposals @@ -92,7 +92,7 @@ remove the scheduled upgrade `Plan`. Of course this requires that the upgrade was known to be a bad idea well before the upgrade itself, to allow time for a vote. -+++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-beta2/proto/cosmos/upgrade/v1beta1/tx.proto#L42-L50 ++++ https://github.com/cosmos/cosmos-sdk/blob/v0.46.0-rc1/proto/cosmos/upgrade/v1beta1/tx.proto#L43-L51 If such a possibility is desired, the upgrade height is to be `2 * (VotingPeriod + DepositPeriod) + (SafetyDelta)` from the beginning of the