chore: remove docs build (#17791)

This commit is contained in:
Marko
2023-09-19 10:03:40 +00:00
committed by GitHub
parent 16293120ab
commit 4ef0130bcd
182 changed files with 188 additions and 24392 deletions
+14
View File
@@ -0,0 +1,14 @@
---
sidebar_position: 1
---
# Overview of `app.go`
This section is intended to provide an overview of the `SimApp` `app.go` file and is still a work in progress.
For now please instead read the [tutorials](https://tutorials.cosmos.network) for a deep dive on how to build a chain.
## Complete `app.go`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go
```
+154
View File
@@ -0,0 +1,154 @@
---
sidebar_position: 1
---
# Overview of `app_v2.go`
:::note Synopsis
The Cosmos SDK allows much easier wiring of an `app.go` thanks to App Wiring and [`depinject`](../packages/01-depinject.md).
Learn more about the rationale of App Wiring in [ADR-057](../architecture/adr-057-app-wiring.md).
:::
:::note Pre-requisite Readings
* [ADR 057: App Wiring](../architecture/adr-057-app-wiring.md)
* [Depinject Documentation](../packages/01-depinject.md)
* [Modules depinject-ready](../building-modules/15-depinject.md)
:::
This section is intended to provide an overview of the `SimApp` `app_v2.go` file with App Wiring.
## `app_config.go`
The `app_config.go` file is the single place to configure all modules parameters.
1. Create the `AppConfig` variable:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L103
```
2. Configure the `runtime` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L103-L167
```
3. Configure the modules defined in the `PreBlocker`, `BeginBlocker` and `EndBlocker` and the `tx` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L112-L129
```
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L200-L203
```
### Complete `app_config.go`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go
```
### Alternative formats
:::tip
The example above shows how to create an `AppConfig` using Go. However, it is also possible to create an `AppConfig` using YAML, or JSON.
The configuration can then be embed with `go:embed` and read with [`appconfig.LoadYAML`](https://pkg.go.dev/cosmossdk.io/core/appconfig#LoadYAML), or [`appconfig.LoadJSON`](https://pkg.go.dev/cosmossdk.io/core/appconfig#LoadJSON), in `app_v2.go`.
```go
//go:embed app_config.yaml
var (
appConfigYaml []byte
appConfig = appconfig.LoadYAML(appConfigYaml)
)
```
:::
```yaml
modules:
- name: runtime
config:
"@type": cosmos.app.runtime.v1alpha1.Module
app_name: SimApp
begin_blockers: [staking, auth, bank]
end_blockers: [bank, auth, staking]
init_genesis: [bank, auth, staking]
- name: auth
config:
"@type": cosmos.auth.module.v1.Module
bech32_prefix: cosmos
- name: bank
config:
"@type": cosmos.bank.module.v1.Module
- name: staking
config:
"@type": cosmos.staking.module.v1.Module
- name: tx
config:
"@type": cosmos.tx.config.v1.Config
```
A more complete example of `app.yaml` can be found [here](https://github.com/cosmos/cosmos-sdk/blob/91b1d83f1339e235a1dfa929ecc00084101a19e3/simapp/app.yaml).
## `app_v2.go`
`app_v2.go` is the place where `SimApp` is constructed. `depinject.Inject` facilitates that by automatically wiring the app modules and keepers, provided an application configuration `AppConfig` is provided. `SimApp` is constructed, when calling the injected `*runtime.AppBuilder`, with `appBuilder.Build(...)`.
In short `depinject` and the [`runtime` package](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/runtime) abstract the wiring of the app, and the `AppBuilder` is the place where the app is constructed. [`runtime`](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/runtime) takes care of registering the codecs, KV store, subspaces and instantiating `baseapp`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_v2.go#L101-L245
```
:::warning
When using `depinject.Inject`, the injected types must be pointers.
:::
### Advanced Configuration
In advanced cases, it is possible to inject extra (module) configuration in a way that is not (yet) supported by `AppConfig`.
In this case, use `depinject.Configs` for combining the extra configuration and `AppConfig`, and `depinject.Supply` to providing that extra configuration.
More information on how work `depinject.Configs` and `depinject.Supply` can be found in the [`depinject` documentation](https://pkg.go.dev/cosmossdk.io/depinject).
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_v2.go#L114-L146
```
### Registering non app wiring modules
It is possible to combine app wiring / depinject enabled modules with non app wiring modules.
To do so, use the `app.RegisterModules` method to register the modules on your app, as well as `app.RegisterStores` for registering the extra stores needed.
```go
// ....
app.App = appBuilder.Build(db, traceStore, baseAppOptions...)
// register module manually
app.RegisterStores(storetypes.NewKVStoreKey(example.ModuleName))
app.ExampleKeeper = examplekeeper.NewKeeper(app.appCodec, app.AccountKeeper.AddressCodec(), runtime.NewKVStoreService(app.GetKey(example.ModuleName)), authtypes.NewModuleAddress(govtypes.ModuleName).String())
exampleAppModule := examplemodule.NewAppModule(app.ExampleKeeper)
if err := app.RegisterModules(&exampleAppModule); err != nil {
panic(err)
}
// ....
```
:::warning
When using AutoCLI and combining app wiring and non app wiring modules. The AutoCLI options should be manually constructed instead of injected.
Otherwise it will miss the non depinject modules and not register their CLI.
:::
### Complete `app_v2.go`
:::tip
Note that in the complete `SimApp` `app_v2.go` file, testing utilities are also defined, but they could as well be defined in a separate file.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_v2.go
```
+172
View File
@@ -0,0 +1,172 @@
---
sidebar_position: 1
---
# Application Mempool
:::note Synopsis
This sections describes how the app-side mempool can be used and replaced.
:::
Since `v0.47` the application has its own mempool to allow much more granular
block building than previous versions. This change was enabled by
[ABCI 1.0](https://github.com/cometbft/cometbft/blob/v0.37.0/spec/abci).
Notably it introduces the `PrepareProposal` and `ProcessProposal` steps of ABCI++.
:::note Pre-requisite Readings
* [BaseApp](../../develop/advanced/00-baseapp.md)
:::
## Prepare Proposal
`PrepareProposal` handles construction of the block, meaning that when a proposer
is preparing to propose a block, it requests the application to evaluate a
`RequestPrepareProposal`, which contains a series of transactions from CometBFT's
mempool. At this point, the application has complete control over the proposal.
It can modify, delete, and inject transactions from it's own app-side mempool into
the proposal or even ignore all the transactions altogether. What the application
does with the transactions provided to it by `RequestPrepareProposal` have no
effect on CometBFT's mempool.
Note, that the application defines the semantics of the `PrepareProposal` and it
MAY be non-deterministic and is only executed by the current block proposer.
Now, reading mempool twice in the previous sentence is confusing, lets break it down.
CometBFT has a mempool that handles gossiping transactions to other nodes
in the network. How these transactions are ordered is determined by CometBFT's
mempool, typically FIFO. However, since the application is able to fully inspect
all transactions, it can provide greater control over transaction ordering.
Allowing the application to handle ordering enables the application to define how
it would like the block constructed.
The Cosmos SDK defines the `DefaultProposalHandler` type, which provides applications with
`PrepareProposal` and `ProcessProposal` handlers. If you decide to implement your
own `PrepareProposal` handler, you must be sure to ensure that the transactions
selected DO NOT exceed the maximum block gas (if set) and the maximum bytes provided
by `req.MaxBytes`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci_utils.go
```
This default implementation can be overridden by the application developer in
favor of a custom implementation in [`app.go`](./01-app-go-v2.md):
```go
prepareOpt := func(app *baseapp.BaseApp) {
abciPropHandler := baseapp.NewDefaultProposalHandler(mempool, app)
app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
}
baseAppOptions = append(baseAppOptions, prepareOpt)
```
## Process Proposal
`ProcessProposal` handles the validation of a proposal from `PrepareProposal`,
which also includes a block header. Meaning, that after a block has been proposed
the other validators have the right to vote on a block. The validator in the
default implementation of `PrepareProposal` runs basic validity checks on each
transaction.
Note, `ProcessProposal` MAY NOT be non-deterministic, i.e. it must be deterministic.
This means if `ProcessProposal` panics or fails and we reject, all honest validator
processes will prevote nil and the CometBFT round will proceed again until a valid
proposal is proposed.
Here is the implementation of the default implementation:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci_utils.go#L153-L159
```
Like `PrepareProposal` this implementation is the default and can be modified by
the application developer in [`app.go`](./01-app-go-v2.md). If you decide to implement
your own `ProcessProposal` handler, you must be sure to ensure that the transactions
provided in the proposal DO NOT exceed the maximum block gas (if set).
```go
processOpt := func(app *baseapp.BaseApp) {
abciPropHandler := baseapp.NewDefaultProposalHandler(mempool, app)
app.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
}
baseAppOptions = append(baseAppOptions, processOpt)
```
## Mempool
Now that we have walked through the `PrepareProposal` & `ProcessProposal`, we can move on to walking through the mempool.
There are countless designs that an application developer can write for a mempool, the SDK opted to provide only simple mempool implementations.
Namely, the SDK provides the following mempools:
* [No-op Mempool](#no-op-mempool)
* [Sender Nonce Mempool](#sender-nonce-mempool)
* [Priority Nonce Mempool](#priority-nonce-mempool)
The default SDK is a [No-op Mempool](#no-op-mempool), but it can be replaced by the application developer in [`app.go`](./01-app-go-v2.md):
```go
nonceMempool := mempool.NewSenderNonceMempool()
mempoolOpt := baseapp.SetMempool(nonceMempool)
baseAppOptions = append(baseAppOptions, mempoolOpt)
```
### No-op Mempool
A no-op mempool is a mempool where transactions are completely discarded and ignored when BaseApp interacts with the mempool.
When this mempool is used, it assumed that an application will rely on CometBFT's transaction ordering defined in `RequestPrepareProposal`,
which is FIFO-ordered by default.
> Note: If a NoOp mempool is used, PrepareProposal and ProcessProposal both should be aware of this as
> PrepareProposal could include transactions that could fail verification in ProcessProposal.
### Sender Nonce Mempool
The nonce mempool is a mempool that keeps transactions from an sorted by nonce in order to avoid the issues with nonces.
It works by storing the transaction in a list sorted by the transaction nonce. When the proposer asks for transactions to be included in a block it randomly selects a sender and gets the first transaction in the list. It repeats this until the mempool is empty or the block is full.
It is configurable with the following parameters:
#### MaxTxs
It is an integer value that sets the mempool in one of three modes, *bounded*, *unbounded*, or *disabled*.
* **negative**: Disabled, mempool does not insert new transaction and return early.
* **zero**: Unbounded mempool has no transaction limit and will never fail with `ErrMempoolTxMaxCapacity`.
* **positive**: Bounded, it fails with `ErrMempoolTxMaxCapacity` when `maxTx` value is the same as `CountTx()`
#### Seed
Set the seed for the random number generator used to select transactions from the mempool.
### Priority Nonce Mempool
The [priority nonce mempool](https://github.com/cosmos/cosmos-sdk/blob/main/types/mempool/priority_nonce_spec.md) is a mempool implementation that stores txs in a partially ordered set by 2 dimensions:
* priority
* sender-nonce (sequence number)
Internally it uses one priority ordered [skip list](https://pkg.go.dev/github.com/huandu/skiplist) and one skip list per sender ordered by sender-nonce (sequence number). When there are multiple txs from the same sender, they are not always comparable by priority to other sender txs and must be partially ordered by both sender-nonce and priority.
It is configurable with the following parameters:
#### MaxTxs
It is an integer value that sets the mempool in one of three modes, *bounded*, *unbounded*, or *disabled*.
* **negative**: Disabled, mempool does not insert new transaction and return early.
* **zero**: Unbounded mempool has no transaction limit and will never fail with `ErrMempoolTxMaxCapacity`.
* **positive**: Bounded, it fails with `ErrMempoolTxMaxCapacity` when `maxTx` value is the same as `CountTx()`
#### Callback
The priority nonce mempool provides mempool options allowing the application sets callback(s).
* **OnRead**: Set a callback to be called when a transaction is read from the mempool.
* **TxReplacement**: Sets a callback to be called when duplicated transaction nonce detected during mempool insert. Application can define a transaction replacement rule based on tx priority or certain transaction fields.
More information on the SDK mempool implementation can be found in the [godocs](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/types/mempool).
+218
View File
@@ -0,0 +1,218 @@
---
sidebar_position: 1
---
# Application Upgrade
:::note
This document describes how to upgrade your application. If you are looking specifically for the changes to perform between SDK versions, see the [SDK migrations documentation](https://docs.cosmos.network/main/migrations/intro).
:::
:::warning
This section is currently incomplete. Track the progress of this document [here](https://github.com/cosmos/cosmos-sdk/issues/11504).
:::
:::note Pre-requisite Readings
* [`x/upgrade` Documentation](https://docs.cosmos.network/main/modules/upgrade)
:::
## General Workflow
Let's assume we are running v0.38.0 of our software in our testnet and want to upgrade to v0.40.0.
How would this look in practice? First of all, we want to finalize the v0.40.0 release candidate
and there install a specially named upgrade handler (eg. "testnet-v2" or even "v0.40.0"). An upgrade
handler should be defined in a new version of the software to define what migrations
to run to migrate from the older version of the software. Naturally, this is app-specific rather
than module specific, and must be defined in `app.go`, even if it imports logic from various
modules to perform the actions. You can register them with `upgradeKeeper.SetUpgradeHandler`
during the app initialization (before starting the abci server), and they serve not only to
perform a migration, but also to identify if this is the old or new version (eg. presence of
a handler registered for the named upgrade).
Once the release candidate along with an appropriate upgrade handler is frozen,
we can have a governance vote to approve this upgrade at some future block height (e.g. 200000).
This is known as an upgrade.Plan. The v0.38.0 code will not know of this handler, but will
continue to run until block 200000, when the plan kicks in at `BeginBlock`. It will check
for existence of the handler, and finding it missing, know that it is running the obsolete software,
and gracefully exit.
Generally the application binary will restart on exit, but then will execute this BeginBlocker
again and exit, causing a restart loop. Either the operator can manually install the new software,
or you can make use of an external watcher daemon to possibly download and then switch binaries,
also potentially doing a backup. The SDK tool for doing such, is called [Cosmovisor](https://docs.cosmos.network/main/tooling/cosmovisor).
When the binary restarts with the upgraded version (here v0.40.0), it will detect we have registered the
"testnet-v2" upgrade handler in the code, and realize it is the new version. It then will run the upgrade handler
and *migrate the database in-place*. Once finished, it marks the upgrade as done, and continues processing
the rest of the block as normal. Once 2/3 of the voting power has upgraded, the blockchain will immediately
resume the consensus mechanism. If the majority of operators add a custom `do-upgrade` script, this should
be a matter of minutes and not even require them to be awake at that time.
## Integrating With An App
::tip
The following is not required for users using `depinject` / app v2, this is abstracted for them.
::
In addition to basic module wiring, setup the upgrade Keeper for the app and then define a `PreBlocker` that calls the upgrade
keeper's PreBlocker method:
```go
func (app *myApp) PreBlocker(ctx sdk.Context, req req.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) {
// For demonstration sake, the app PreBlocker only returns the upgrade module pre-blocker.
// In a real app, the module manager should call all pre-blockers
// return return app.ModuleManager.PreBlock(ctx, req)
return app.upgradeKeeper.PreBlocker(ctx, req)
}
```
The app must then integrate the upgrade keeper with its governance module as appropriate. The governance module
should call ScheduleUpgrade to schedule an upgrade and ClearUpgradePlan to cancel a pending upgrade.
## Performing Upgrades
Upgrades can be scheduled at a predefined block height. Once this block height is reached, the
existing software will cease to process ABCI messages and a new version with code that handles the upgrade must be deployed.
All upgrades are coordinated by a unique upgrade name that cannot be reused on the same blockchain. In order for the upgrade
module to know that the upgrade has been safely applied, a handler with the name of the upgrade must be installed.
Here is an example handler for an upgrade named "my-fancy-upgrade":
```go
app.upgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx context.Context, plan upgrade.Plan) {
// Perform any migrations of the state store needed for this upgrade
})
```
This upgrade handler performs the dual function of alerting the upgrade module that the named upgrade has been applied,
as well as providing the opportunity for the upgraded software to perform any necessary state migrations. Both the halt
(with the old binary) and applying the migration (with the new binary) are enforced in the state machine. Actually
switching the binaries is an ops task and not handled inside the sdk / abci app.
Here is a sample code to set store migrations with an upgrade:
```go
// this configures a no-op upgrade handler for the "my-fancy-upgrade" upgrade
app.UpgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx context.Context, plan upgrade.Plan) {
// upgrade changes here
})
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
// handle error
}
if upgradeInfo.Name == "my-fancy-upgrade" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
storeUpgrades := store.StoreUpgrades{
Renamed: []store.StoreRename{{
OldKey: "foo",
NewKey: "bar",
}},
Deleted: []string{},
}
// configure store loader that checks if version == upgradeHeight and applies store upgrades
app.SetStoreLoader(upgrade.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades))
}
```
## Halt Behavior
Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error
that looks like:
```text
UPGRADE "<Name>" NEEDED at height <NNNN>: <Info>
```
where `Name` and `Info` are the values of the respective fields on the upgrade Plan.
To perform the actual halt of the blockchain, the upgrade keeper simply panics which prevents the ABCI state machine
from proceeding but doesn't actually exit the process. Exiting the process can cause issues for other nodes that start
to lose connectivity with the exiting nodes, thus this module prefers to just halt but not exit.
## Automation
Read more about [Cosmovisor](https://docs.cosmos.network/main/tooling/cosmovisor), the tool for automating upgrades.
## Canceling Upgrades
There are two ways to cancel a planned upgrade - with on-chain governance or off-chain social consensus.
For the first one, there is a `CancelSoftwareUpgrade` governance proposal, which can be voted on and will
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. If you want to allow such a possibility, you
should set the upgrade height to be `2 * (votingperiod + depositperiod) + (safety delta)` from the beginning of
the first upgrade proposal. Safety delta is the time available from the success of an upgrade proposal
and the realization it was a bad idea (due to external testing). You can also start a `CancelSoftwareUpgrade`
proposal while the original `SoftwareUpgrade` proposal is still being voted upon, as long as the voting
period ends after the `SoftwareUpgrade` proposal.
However, let's assume that we don't realize the upgrade has a bug until shortly before it will occur
(or while we try it out - hitting some panic in the migration). It would seem the blockchain is stuck,
but we need to allow an escape for social consensus to overrule the planned upgrade. To do so, there's
a `--unsafe-skip-upgrades` flag to the start command, which will cause the node to mark the upgrade
as done upon hitting the planned upgrade height(s), without halting and without actually performing a migration.
If over two-thirds run their nodes with this flag on the old binary, it will allow the chain to continue through
the upgrade with a manual override. (This must be well-documented for anyone syncing from genesis later on).
Example:
```shell
<appd> start --unsafe-skip-upgrades <height1> <optional_height_2> ... <optional_height_N>
```
## Pre-Upgrade Handling
Cosmovisor supports custom pre-upgrade handling. Use pre-upgrade handling when you need to implement application config changes that are required in the newer version before you perform the upgrade.
Using Cosmovisor pre-upgrade handling is optional. If pre-upgrade handling is not implemented, the upgrade continues.
For example, make the required new-version changes to `app.toml` settings during the pre-upgrade handling. The pre-upgrade handling process means that the file does not have to be manually updated after the upgrade.
Before the application binary is upgraded, Cosmovisor calls a `pre-upgrade` command that can be implemented by the application.
The `pre-upgrade` command does not take in any command-line arguments and is expected to terminate with the following exit codes:
| Exit status code | How it is handled in Cosmosvisor |
|------------------|---------------------------------------------------------------------------------------------------------------------|
| `0` | Assumes `pre-upgrade` command executed successfully and continues the upgrade. |
| `1` | Default exit code when `pre-upgrade` command has not been implemented. |
| `30` | `pre-upgrade` command was executed but failed. This fails the entire upgrade. |
| `31` | `pre-upgrade` command was executed but failed. But the command is retried until exit code `1` or `30` are returned. |
## Sample
Here is a sample structure of the `pre-upgrade` command:
```go
func preUpgradeCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "pre-upgrade",
Short: "Pre-upgrade command",
Long: "Pre-upgrade command to implement custom pre-upgrade handling",
Run: func(cmd *cobra.Command, args []string) {
err := HandlePreUpgrade()
if err != nil {
os.Exit(30)
}
os.Exit(0)
},
}
return cmd
}
```
Ensure that the pre-upgrade command has been registered in the application:
```go
rootCmd.AddCommand(
// ..
preUpgradeCommand(),
// ..
)
```
When not using Cosmovisor, ensure to run `<appd> pre-upgrade` before starting the application binary.
+121
View File
@@ -0,0 +1,121 @@
---
sidebar_position: 1
---
# Vote Extensions
:::note Synopsis
This sections describes how the application can define and use vote extensions
defined in ABCI++.
:::
## Extend Vote
ABCI++ allows an application to extend a pre-commit vote with arbitrary data. This
process does NOT have be deterministic and the data returned can be unique to the
validator process. The Cosmos SDK defines `baseapp.ExtendVoteHandler`:
```go
type ExtendVoteHandler func(Context, *abci.RequestExtendVote) (*abci.ResponseExtendVote, error)
```
An application can set this handler in `app.go` via the `baseapp.SetExtendVoteHandler`
`BaseApp` option function. The `sdk.ExtendVoteHandler`, if defined, is called during
the `ExtendVote` ABCI method. Note, if an application decides to implement
`baseapp.ExtendVoteHandler`, it MUST return a non-nil `VoteExtension`. However, the vote
extension can be empty. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/spec/abci/abci++_methods.md#extendvote)
for more details.
There are many decentralized censorship-resistant use cases for vote extensions.
For example, a validator may want to submit prices for a price oracle or encryption
shares for an encrypted transaction mempool. Note, an application should be careful
to consider the size of the vote extensions as they could increase latency in block
production. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/docs/qa/CometBFT-QA-38.md#vote-extensions-testbed)
for more details.
## Verify Vote Extension
Similar to extending a vote, an application can also verify vote extensions from
other validators when validating their pre-commits. For a given vote extension,
this process MUST be deterministic. The Cosmos SDK defines `sdk.VerifyVoteExtensionHandler`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/abci.go#L26-L27
```
An application can set this handler in `app.go` via the `baseapp.SetVerifyVoteExtensionHandler`
`BaseApp` option function. The `sdk.VerifyVoteExtensionHandler`, if defined, is called
during the `VerifyVoteExtension` ABCI method. If an application defines a vote
extension handler, it should also define a verification handler. Note, not all
validators will share the same view of what vote extensions they verify depending
on how votes are propagated. See [here](https://github.com/cometbft/cometbft/blob/v0.38.0-rc1/spec/abci/abci++_methods.md#verifyvoteextension)
for more details.
## Vote Extension Propagation
The agreed upon vote extensions at height `H` are provided to the proposing validator
at height `H+1` during `PrepareProposal`. As a result, the vote extensions are
not natively provided or exposed to the remaining validators during `ProcessProposal`.
As a result, if an application requires that the agreed upon vote extensions from
height `H` are available to all validators at `H+1`, the application must propagate
these vote extensions manually in the block proposal itself. This can be done by
"injecting" them into the block proposal, since the `Txs` field in `PrepareProposal`
is just a slice of byte slices.
`FinalizeBlock` will ignore any byte slice that doesn't implement an `sdk.Tx` so
any injected vote extensions will safely be ignored in `FinalizeBlock`. For more
details on propagation, see the [ABCI++ 2.0 ADR](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-064-abci-2.0.md#vote-extension-propagation--verification).
### Recovery of injected Vote Extensions
As stated before, vote extensions can be injected in a block proposal (along with
other transactions in the `Txs` field). The Cosmos SDK provides a pre-FinalizeBlock
hook to allow applications to recover vote extensions, perform any necessary
computation on them, and then store the results in the cached store. These results
will be available to the application during the subsequent `FinalizeBlock` call.
An example of how a pre-FinalizeBlock hook could look like is shown below:
```go
app.SetPreBlocker(func(ctx sdk.Context, req *abci.RequestFinalizeBlock) error {
allVEs := []VE{} // store all parsed vote extensions here
for _, tx := range req.Txs {
// define a custom function that tries to parse the tx as a vote extension
ve, ok := parseVoteExtension(tx)
if !ok {
continue
}
allVEs = append(allVEs, ve)
}
// perform any necessary computation on the vote extensions and store the result
// in the cached store
result := compute(allVEs)
err := storeVEResult(ctx, result)
if err != nil {
return err
}
return nil
})
```
Then in an app's module the application can retrieve the result of the computation
of vote extensions from the cached store:
```go
func (k Keeper) BeginBlocker(ctx context.Context) error {
// retrieve the result of the computation of vote extensions from the cached store
result, err := k.GetVEResult(ctx)
if err != nil {
return err
}
// use the result of the computation of vote extensions
k.setSomething(result)
return nil
}
```
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Building Apps",
"position": 0,
"link": null
}
+92
View File
@@ -0,0 +1,92 @@
---
sidebar_position: 1
---
# Introduction to Cosmos SDK Modules
:::note Synopsis
Modules define most of the logic of Cosmos SDK applications. Developers compose modules together using the Cosmos SDK to build their custom application-specific blockchains. This document outlines the basic concepts behind SDK modules and how to approach module management.
:::
:::note Pre-requisite Readings
* [Anatomy of a Cosmos SDK application](../../develop/beginner/00-app-anatomy.md)
* [Lifecycle of a Cosmos SDK transaction](../../develop/beginner/01-tx-lifecycle.md)
:::
## Role of Modules in a Cosmos SDK Application
The Cosmos SDK can be thought of as the Ruby-on-Rails of blockchain development. It comes with a core that provides the basic functionalities every blockchain application needs, like a [boilerplate implementation of the ABCI](../../develop/advanced/00-baseapp.md) to communicate with the underlying consensus engine, a [`multistore`](../../develop/advanced/04-store.md#multistore) to persist state, a [server](../../develop/advanced/03-node.md) to form a full-node and [interfaces](./09-module-interfaces.md) to handle queries.
On top of this core, the Cosmos SDK enables developers to build modules that implement the business logic of their application. In other words, SDK modules implement the bulk of the logic of applications, while the core does the wiring and enables modules to be composed together. The end goal is to build a robust ecosystem of open-source Cosmos SDK modules, making it increasingly easier to build complex blockchain applications.
Cosmos SDK modules can be seen as little state-machines within the state-machine. They generally define a subset of the state using one or more `KVStore`s in the [main multistore](../../develop/advanced/04-store.md), as well as a subset of [message types](./02-messages-and-queries.md#messages). These messages are routed by one of the main components of Cosmos SDK core, [`BaseApp`](../../develop/advanced/00-baseapp.md), to a module Protobuf [`Msg` service](./03-msg-services.md) that defines them.
```text
+
|
| Transaction relayed from the full-node's consensus engine
| to the node's application via DeliverTx
|
|
|
+---------------------v--------------------------+
| APPLICATION |
| |
| Using baseapp's methods: Decode the Tx, |
| extract and route the message(s) |
| |
+---------------------+--------------------------+
|
|
|
+---------------------------+
|
|
|
| Message routed to the correct
| module to be processed
|
|
+----------------+ +---------------+ +----------------+ +------v----------+
| | | | | | | |
| AUTH MODULE | | BANK MODULE | | STAKING MODULE | | GOV MODULE |
| | | | | | | |
| | | | | | | Handles message,|
| | | | | | | Updates state |
| | | | | | | |
+----------------+ +---------------+ +----------------+ +------+----------+
|
|
|
|
+--------------------------+
|
| Return result to the underlying consensus engine (e.g. CometBFT)
| (0=Ok, 1=Err)
v
```
As a result of this architecture, building a Cosmos SDK application usually revolves around writing modules to implement the specialized logic of the application and composing them with existing modules to complete the application. Developers will generally work on modules that implement logic needed for their specific use case that do not exist yet, and will use existing modules for more generic functionalities like staking, accounts, or token management.
## How to Approach Building Modules as a Developer
While there are no definitive guidelines for writing modules, here are some important design principles developers should keep in mind when building them:
* **Composability**: Cosmos SDK applications are almost always composed of multiple modules. This means developers need to carefully consider the integration of their module not only with the core of the Cosmos SDK, but also with other modules. The former is achieved by following standard design patterns outlined [here](#main-components-of-sdk-modules), while the latter is achieved by properly exposing the store(s) of the module via the [`keeper`](./06-keeper.md).
* **Specialization**: A direct consequence of the **composability** feature is that modules should be **specialized**. Developers should carefully establish the scope of their module and not batch multiple functionalities into the same module. This separation of concerns enables modules to be re-used in other projects and improves the upgradability of the application. **Specialization** also plays an important role in the [object-capabilities model](../../develop/advanced/10-ocap.md) of the Cosmos SDK.
* **Capabilities**: Most modules need to read and/or write to the store(s) of other modules. However, in an open-source environment, it is possible for some modules to be malicious. That is why module developers need to carefully think not only about how their module interacts with other modules, but also about how to give access to the module's store(s). The Cosmos SDK takes a capabilities-oriented approach to inter-module security. This means that each store defined by a module is accessed by a `key`, which is held by the module's [`keeper`](./06-keeper.md). This `keeper` defines how to access the store(s) and under what conditions. Access to the module's store(s) is done by passing a reference to the module's `keeper`.
## Main Components of Cosmos SDK Modules
Modules are by convention defined in the `./x/` subfolder (e.g. the `bank` module will be defined in the `./x/bank` folder). They generally share the same core components:
* A [`keeper`](./06-keeper.md), used to access the module's store(s) and update the state.
* A [`Msg` service](./02-messages-and-queries.md#messages), used to process messages when they are routed to the module by [`BaseApp`](../../develop/advanced/00-baseapp.md#message-routing) and trigger state-transitions.
* A [query service](./04-query-services.md), used to process user queries when they are routed to the module by [`BaseApp`](../../develop/advanced/00-baseapp.md#query-routing).
* Interfaces, for end users to query the subset of the state defined by the module and create `message`s of the custom types defined in the module.
In addition to these components, modules implement the `AppModule` interface in order to be managed by the [`module manager`](./01-module-manager.md).
Please refer to the [structure document](./11-structure.md) to learn about the recommended structure of a module's directory.
+330
View File
@@ -0,0 +1,330 @@
---
sidebar_position: 1
---
# Module Manager
:::note Synopsis
Cosmos SDK modules need to implement the [`AppModule` interfaces](#application-module-interfaces), in order to be managed by the application's [module manager](#module-manager). The module manager plays an important role in [`message` and `query` routing](../../develop/advanced/00-baseapp.md#routing), and allows application developers to set the order of execution of a variety of functions like [`PreBlocker`](../../develop/beginner/00-app-anatomy#preblocker) and [`BeginBlocker` and `EndBlocker`](../../develop/beginner/00-app-anatomy.md#begingblocker-and-endblocker).
:::
:::note Pre-requisite Readings
* [Introduction to Cosmos SDK Modules](./00-intro.md)
:::
## Application Module Interfaces
Application module interfaces exist to facilitate the composition of modules together to form a functional Cosmos SDK application.
:::note
It is recommended to implement interfaces from the [Core API](https://docs.cosmos.network/main/architecture/adr-063-core-module-api) `appmodule` package. This makes modules less dependent on the SDK.
For legacy reason modules can still implement interfaces from the SDK `module` package.
:::
There are 2 main application module interfaces:
* [`appmodule.AppModule` / `module.AppModule`](#appmodule) for inter-dependent module functionalities (except genesis-related functionalities).
* (legacy) [`module.AppModuleBasic`](#appmodulebasic) for independent module functionalities. New modules can use `module.CoreAppModuleBasicAdaptor` instead.
The above interfaces are mostly embedding smaller interfaces (extension interfaces), that defines specific functionalities:
* (legacy) `module.HasName`: Allows the module to provide its own name for legacy purposes.
* (legacy) [`module.HasGenesisBasics`](#modulehasgenesisbasics): The legacy interface for stateless genesis methods.
* [`module.HasGenesis`](#modulehasgenesis) for inter-dependent genesis-related module functionalities.
* [`module.HasABCIGenesis`](#modulehasabcigenesis) for inter-dependent genesis-related module functionalities.
* [`appmodule.HasGenesis` / `module.HasGenesis`](#appmodulehasgenesis): The extension interface for stateful genesis methods.
* [`appmodule.HasPreBlocker`](#haspreblocker): The extension interface that contains information about the `AppModule` and `PreBlock`.
* [`appmodule.HasBeginBlocker`](#hasbeginblocker): The extension interface that contains information about the `AppModule` and `BeginBlock`.
* [`appmodule.HasEndBlocker`](#hasendblocker): The extension interface that contains information about the `AppModule` and `EndBlock`.
* [`appmodule.HasPrecommit`](#hasprecommit): The extension interface that contains information about the `AppModule` and `Precommit`.
* [`appmodule.HasPrepareCheckState`](#haspreparecheckstate): The extension interface that contains information about the `AppModule` and `PrepareCheckState`.
* [`appmodule.HasService` / `module.HasServices`](#hasservices): The extension interface for modules to register services.
* [`module.HasABCIEndBlock`](#hasabciendblock): The extension interface that contains information about the `AppModule`, `EndBlock` and returns an updated validator set.
* (legacy) [`module.HasInvariants`](#hasinvariants): The extension interface for registering invariants.
* (legacy) [`module.HasConsensusVersion`](#hasconsensusversion): The extension interface for declaring a module consensus version.
The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../../develop/beginner/00-app-anatomy.md#core-application-file).
The `AppModule` interface exists to define inter-dependent module methods. Many modules need to interact with other modules, typically through [`keeper`s](./06-keeper.md), which means there is a need for an interface where modules list their `keeper`s and other methods that require a reference to another module's object. `AppModule` interface extension, such as `HasBeginBlocker` and `HasEndBlocker`, also enables the module manager to set the order of execution between module's methods like `BeginBlock` and `EndBlock`, which is important in cases where the order of execution between modules matters in the context of the application.
The usage of extension interfaces allows modules to define only the functionalities they need. For example, a module that does not need an `EndBlock` does not need to define the `HasEndBlocker` interface and thus the `EndBlock` method. `AppModule` and `AppModuleGenesis` are voluntarily small interfaces, that can take advantage of the `Module` patterns without having to define many placeholder functions.
### `AppModuleBasic`
:::note
Use `module.CoreAppModuleBasicAdaptor` instead for creating an `AppModuleBasic` from an `appmodule.AppModule`.
:::
The `AppModuleBasic` interface defines the independent methods modules need to implement.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L56-L66
```
Let us go through the methods:
* `RegisterLegacyAminoCodec(*codec.LegacyAmino)`: Registers the `amino` codec for the module, which is used to marshal and unmarshal structs to/from `[]byte` in order to persist them in the module's `KVStore`.
* `RegisterInterfaces(codectypes.InterfaceRegistry)`: Registers a module's interface types and their concrete implementations as `proto.Message`.
* `RegisterGRPCGatewayRoutes(client.Context, *runtime.ServeMux)`: Registers gRPC routes for the module.
All the `AppModuleBasic` of an application are managed by the [`BasicManager`](#basicmanager).
### `HasName`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L71-L73
```
* `HasName` is an interface that has a method `Name()`. This method returns the name of the module as a `string`.
### Genesis
:::tip
For easily creating an `AppModule` that only has genesis functionalities, use `module.GenesisOnlyAppModule`.
:::
#### `module.HasGenesisBasics`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L76-L79
```
Let us go through the methods:
* `DefaultGenesis(codec.JSONCodec)`: Returns a default [`GenesisState`](./08-genesis.md#genesisstate) for the module, marshalled to `json.RawMessage`. The default `GenesisState` need to be defined by the module developer and is primarily used for testing.
* `ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)`: Used to validate the `GenesisState` defined by a module, given in its `json.RawMessage` form. It will usually unmarshall the `json` before running a custom [`ValidateGenesis`](./08-genesis.md#validategenesis) function defined by the module developer.
#### `module.HasGenesis`
`HasGenesis` is an extension interface for allowing modules to implement genesis functionalities.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/6ce2505/types/module/module.go#L184-L189
```
#### `module.HasABCIGenesis`
`HasABCIGenesis` is an extension interface for allowing modules to implement genesis functionalities and returns validator set updates.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/6ce2505/types/module/module.go#L191-L196
```
#### `appmodule.HasGenesis`
:::warning
`appmodule.HasGenesis` is experimental and should be considered unstable, it is recommended to not use this interface at this time.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/6ce2505/core/appmodule/genesis.go#L8-L25
```
### `AppModule`
The `AppModule` interface defines a module. Modules can declare their functionalities by implementing extensions interfaces.
`AppModule`s are managed by the [module manager](#manager), which checks which extension interfaces are implemented by the module.
#### `appmodule.AppModule`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/6afece6/core/appmodule/module.go#L11-L20
```
#### `module.AppModule`
:::note
Previously the `module.AppModule` interface was containing all the methods that are defined in the extensions interfaces. This was leading to much boilerplate for modules that did not need all the functionalities.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L195-L199
```
### `HasInvariants`
This interface defines one method. It allows to checks if a module can register invariants.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L202-L205
```
* `RegisterInvariants(sdk.InvariantRegistry)`: Registers the [`invariants`](./07-invariants.md) of the module. If an invariant deviates from its predicted value, the [`InvariantRegistry`](./07-invariants.md#registry) triggers appropriate logic (most often the chain will be halted).
### `HasServices`
This interface defines one method. It allows to checks if a module can register invariants.
#### `appmodule.HasService`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/6afece6/core/appmodule/module.go#L22-L40
```
#### `module.HasServices`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L208-L211
```
* `RegisterServices(Configurator)`: Allows a module to register services.
### `HasConsensusVersion`
This interface defines one method for checking a module consensus version.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L214-L220
```
* `ConsensusVersion() uint64`: Returns the consensus version of the module.
### `HasPreBlocker`
The `HasPreBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `PreBlock` method implement this interface.
### `HasBeginBlocker`
The `HasBeginBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `BeginBlock` method implement this interface.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L56-L63
```
* `BeginBlock(context.Context) error`: This method gives module developers the option to implement logic that is automatically triggered at the beginning of each block.
### `HasEndBlocker`
The `HasEndBlocker` is an extension interface from `appmodule.AppModule`. All modules that have an `EndBlock` method implement this interface. If a module need to return validator set updates (staking), they can use `HasABCIEndBlock`
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L66-L72
```
* `EndBlock(context.Context) error`: This method gives module developers the option to implement logic that is automatically triggered at the end of each block.
### `HasABCIEndBlock`
The `HasABCIEndBlock` is an extension interface from `module.AppModule`. All modules that have an `EndBlock` which return validator set updates implement this interface.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L222-L225
```
* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: This method gives module developers the option to inform the underlying consensus engine of validator set changes (e.g. the `staking` module).
### `HasPrecommit`
`HasPrecommit` is an extension interface from `appmodule.AppModule`. All modules that have a `Precommit` method implement this interface.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L49-L52
```
* `Precommit(context.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../../develop/advanced/00-baseapp.md#commit) of each block using the [`finalizeblockstate`](../../develop/advanced/00-baseapp.md#state-updates) of the block to be committed. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
### `HasPrepareCheckState`
`HasPrepareCheckState` is an extension interface from `appmodule.AppModule`. All modules that have a `PrepareCheckState` method implement this interface.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/appmodule/module.go#L49-L52
```
* `PrepareCheckState(context.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../../develop/advanced/00-baseapp.md#commit) of each block using the [`checkState`](../../develop/advanced/00-baseapp.md#state-updates) of the next block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module.
### Implementing the Application Module Interfaces
Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`).
Almost every module needs to implement the `AppModuleBasic` and `AppModule` interfaces. If the module is only used for genesis, it will implement `AppModuleGenesis` instead of `AppModule`. The concrete type that implements the interface can add parameters that are required for the implementation of the various methods of the interface. For example, the `Route()` function often calls a `NewMsgServerImpl(k keeper)` function defined in `keeper/msg_server.go` and therefore needs to pass the module's [`keeper`](./06-keeper.md) as a parameter.
```go
// example
type AppModule struct {
AppModuleBasic
keeper Keeper
}
```
In the example above, you can see that the `AppModule` concrete type references an `AppModuleBasic`, and not an `AppModuleGenesis`. That is because `AppModuleGenesis` only needs to be implemented in modules that focus on genesis-related functionalities. In most modules, the concrete `AppModule` type will have a reference to an `AppModuleBasic` and implement the two added methods of `AppModuleGenesis` directly in the `AppModule` type.
If no parameter is required (which is often the case for `AppModuleBasic`), just declare an empty concrete type like so:
```go
type AppModuleBasic struct{}
```
## Module Managers
Module managers are used to manage collections of `AppModuleBasic` and `AppModule`.
### `BasicManager`
The `BasicManager` is a structure that lists all the `AppModuleBasic` of an application:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L82
```
It implements the following methods:
* `NewBasicManager(modules ...AppModuleBasic)`: Constructor function. It takes a list of the application's `AppModuleBasic` and builds a new `BasicManager`. This function is generally called in the `init()` function of [`app.go`](../../develop/beginner/00-app-anatomy.md#core-application-file) to quickly initialize the independent elements of the application's modules (click [here](https://github.com/cosmos/gaia/blob/main/app/app.go#L59-L74) to see an example).
* `NewBasicManagerFromManager(manager *Manager, customModuleBasics map[string]AppModuleBasic)`: Contructor function. It creates a new `BasicManager` from a `Manager`. The `BasicManager` will contain all `AppModuleBasic` from the `AppModule` manager using `CoreAppModuleBasicAdaptor` whenever possible. Module's `AppModuleBasic` can be overridden by passing a custom AppModuleBasic map
* `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)`: Registers the [`codec.LegacyAmino`s](../../develop/advanced/05-encoding.md#amino) of each of the application's `AppModuleBasic`. This function is usually called early on in the [application's construction](../../develop/beginner/00-app-anatomy.md#constructor).
* `RegisterInterfaces(registry codectypes.InterfaceRegistry)`: Registers interface types and implementations of each of the application's `AppModuleBasic`.
* `DefaultGenesis(cdc codec.JSONCodec)`: Provides default genesis information for modules in the application by calling the [`DefaultGenesis(cdc codec.JSONCodec)`](./08-genesis.md#defaultgenesis) function of each module. It only calls the modules that implements the `HasGenesisBasics` interfaces.
* `ValidateGenesis(cdc codec.JSONCodec, txEncCfg client.TxEncodingConfig, genesis map[string]json.RawMessage)`: Validates the genesis information modules by calling the [`ValidateGenesis(codec.JSONCodec, client.TxEncodingConfig, json.RawMessage)`](./08-genesis.md#validategenesis) function of modules implementing the `HasGenesisBasics` interface.
* `RegisterGRPCGatewayRoutes(clientCtx client.Context, rtr *runtime.ServeMux)`: Registers gRPC routes for modules.
* `AddTxCommands(rootTxCmd *cobra.Command)`: Adds modules' transaction commands (defined as `GetTxCmd() *cobra.Command`) to the application's [`rootTxCommand`](../../develop/advanced/07-cli.md#transaction-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../../develop/advanced/07-cli.md).
* `AddQueryCommands(rootQueryCmd *cobra.Command)`: Adds modules' query commands (defined as `GetQueryCmd() *cobra.Command`) to the application's [`rootQueryCommand`](../../develop/advanced/07-cli.md#query-commands). This function is usually called function from the `main.go` function of the [application's command-line interface](../../develop/advanced/07-cli.md).
### `Manager`
The `Manager` is a structure that holds all the `AppModule` of an application, and defines the order of execution between several key components of these modules:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/module/module.go#L267-L276
```
The module manager is used throughout the application whenever an action on a collection of modules is required. It implements the following methods:
* `NewManager(modules ...AppModule)`: Constructor function. It takes a list of the application's `AppModule`s and builds a new `Manager`. It is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderInitGenesis(moduleNames ...string)`: Sets the order in which the [`InitGenesis`](./08-genesis.md#initgenesis) function of each module will be called when the application is first started. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
To initialize modules successfully, module dependencies should be considered. For example, the `genutil` module must occur after `staking` module so that the pools are properly initialized with tokens from genesis accounts, the `genutils` module must also occur after `auth` so that it can access the params from auth, IBC's `capability` module should be initialized before all other modules so that it can initialize any capabilities.
* `SetOrderExportGenesis(moduleNames ...string)`: Sets the order in which the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module will be called in case of an export. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderPreBlockers(moduleNames ...string)`: Sets the order in which the `PreBlock()` function of each module will be called before `BeginBlock()` of all modules. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the end of each block. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderPrecommiters(moduleNames ...string)`: Sets the order in which the `Precommit()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderPrepareCheckStaters(moduleNames ...string)`: Sets the order in which the `PrepareCheckState()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
* `SetOrderMigrations(moduleNames ...string)`: Sets the order of migrations to be run. If not set then migrations will be run with an order defined in `DefaultMigrationsOrder`.
* `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./07-invariants.md) of module implementing the `HasInvariants` interface.
* `RegisterServices(cfg Configurator)`: Registers the services of modules implementing the `HasServices` interface.
* `InitGenesis(ctx context.Context, cdc codec.JSONCodec, genesisData map[string]json.RawMessage)`: Calls the [`InitGenesis`](./08-genesis.md#initgenesis) function of each module when the application is first started, in the order defined in `OrderInitGenesis`. Returns an `abci.ResponseInitChain` to the underlying consensus engine, which can contain validator updates.
* `ExportGenesis(ctx context.Context, cdc codec.JSONCodec)`: Calls the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module, in the order defined in `OrderExportGenesis`. The export constructs a genesis file from a previously existing state, and is mainly used when a hard-fork upgrade of the chain is required.
* `ExportGenesisForModules(ctx context.Context, cdc codec.JSONCodec, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export.
* `BeginBlock(ctx context.Context) error`: At the beginning of each block, this function is called from [`BaseApp`](../../develop/advanced/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./06-beginblock-endblock.md) function of each modules implementing the `appmodule.HasBeginBlocker` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../../develop/advanced/02-context.md) with an event manager to aggregate [events](../../develop/advanced/08-events.md) emitted from each modules.
* `EndBlock(ctx context.Context) error`: At the end of each block, this function is called from [`BaseApp`](../../develop/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-beginblock-endblock.md) function of each modules implementing the `appmodule.HasEndBlocker` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../develop/advanced/02-context.md) with an event manager to aggregate [events](../../develop/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any).
* `EndBlock(context.Context) ([]abci.ValidatorUpdate, error)`: At the end of each block, this function is called from [`BaseApp`](../../develop/advanced/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./06-beginblock-endblock.md) function of each modules implementing the `module.HasABCIEndBlock` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../../develop/advanced/02-context.md) with an event manager to aggregate [events](../../develop/advanced/08-events.md) emitted from all modules. The function returns an `abci` which contains the aforementioned events, as well as validator set updates (if any).
* `Precommit(ctx context.Context)`: During [`Commit`](../../develop/advanced/00-baseapp.md#commit), this function is called from `BaseApp` immediately before the [`deliverState`](../../develop/advanced/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../../develop/advanced/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `HasPrecommit` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../../develop/advanced/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`finalizeblockstate`](../../develop/advanced/00-baseapp.md#state-updates).
* `PrepareCheckState(ctx context.Context)`: During [`Commit`](../../develop/advanced/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../../develop/advanced/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../../develop/advanced/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `HasPrepareCheckState` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../../develop/advanced/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../../develop/advanced/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../../develop/advanced/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block.
Here's an example of a concrete integration within an `simapp`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app.go#L411-L434
```
This is the same example from `runtime` (the package that powers app v2):
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/runtime/module.go#L61
```
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/runtime/module.go#L82
```
+137
View File
@@ -0,0 +1,137 @@
---
sidebar_position: 1
---
# Messages and Queries
:::note Synopsis
`Msg`s and `Queries` are the two primary objects handled by modules. Most of the core components defined in a module, like `Msg` services, `keeper`s and `Query` services, exist to process `message`s and `queries`.
:::
:::note Pre-requisite Readings
* [Introduction to Cosmos SDK Modules](./00-intro.md)
:::
## Messages
`Msg`s are objects whose end-goal is to trigger state-transitions. They are wrapped in [transactions](../../develop/advanced/01-transactions.md), which may contain one or more of them.
When a transaction is relayed from the underlying consensus engine to the Cosmos SDK application, it is first decoded by [`BaseApp`](../../develop/advanced/00-baseapp.md). Then, each message contained in the transaction is extracted and routed to the appropriate module via `BaseApp`'s `MsgServiceRouter` so that it can be processed by the module's [`Msg` service](./03-msg-services.md). For a more detailed explanation of the lifecycle of a transaction, click [here](../../develop/beginner/01-tx-lifecycle.md).
### `Msg` Services
Defining Protobuf `Msg` services is the recommended way to handle messages. A Protobuf `Msg` service should be created for each module, typically in `tx.proto` (see more info about [conventions and naming](../../develop/advanced/05-encoding.md#faq)). It must have an RPC service method defined for each message in the module.
Each `Msg` service method must have exactly one argument, which must implement the `sdk.Msg` interface, and a Protobuf response. The naming convention is to call the RPC argument `Msg<service-rpc-name>` and the RPC response `Msg<service-rpc-name>Response`. For example:
```protobuf
rpc Send(MsgSend) returns (MsgSendResponse);
```
See an example of a `Msg` service definition from `x/bank` module:
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/bank/v1beta1/tx.proto#L13-L36
```
### `sdk.Msg` Interface
`sdk.Msg` is a alias of `proto.Message`.
To attach a `ValidateBasic()` method to a message then you must add methods to the type adhereing to the `HasValidateBasic`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/9c1e8b247cd47b5d3decda6e86fbc3bc996ee5d7/types/tx_msg.go#L84-L88
```
In 0.50+ signers from the `GetSigners()` call is automated via a protobuf annotation.
Read more about the signer field [here](./05-protobuf-annotations.md).
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/e6848d99b55a65d014375b295bdd7f9641aac95e/proto/cosmos/bank/v1beta1/tx.proto#L40
```
If there is a need for custom signers then there is an alternative path which can be taken. A function which returns `signing.CustomGetSigner` for a specific message can be defined.
```go
func ProvideBankSendTransactionGetSigners() signing.CustomGetSigner {
// Extract the signer from the signature.
signer, err := coretypes.LatestSigner(Tx).Sender(ethTx)
if err != nil {
return nil, err
}
// Return the signer in the required format.
return [][]byte{signer.Bytes()}, nil
}
```
When using dependency injection (depinject) this can be provided to the application via the provide method.
```go
depinject.Provide(banktypes.ProvideBankSendTransactionGetSigners)
```
The Cosmos SDK uses Protobuf definitions to generate client and server code:
* `MsgServer` interface defines the server API for the `Msg` service and its implementation is described as part of the [`Msg` services](./03-msg-services.md) documentation.
* Structures are generated for all RPC request and response types.
A `RegisterMsgServer` method is also generated and should be used to register the module's `MsgServer` implementation in `RegisterServices` method from the [`AppModule` interface](./01-module-manager.md#appmodule).
In order for clients (CLI and grpc-gateway) to have these URLs registered, the Cosmos SDK provides the function `RegisterMsgServiceDesc(registry codectypes.InterfaceRegistry, sd *grpc.ServiceDesc)` that should be called inside module's [`RegisterInterfaces`](01-module-manager.md#appmodulebasic) method, using the proto-generated `&_Msg_serviceDesc` as `*grpc.ServiceDesc` argument.
## Queries
A `query` is a request for information made by end-users of applications through an interface and processed by a full-node. A `query` is received by a full-node through its consensus engine and relayed to the application via the ABCI. It is then routed to the appropriate module via `BaseApp`'s `QueryRouter` so that it can be processed by the module's query service (./04-query-services.md). For a deeper look at the lifecycle of a `query`, click [here](../../develop/beginner/02-query-lifecycle.md).
### gRPC Queries
Queries should be defined using [Protobuf services](https://developers.google.com/protocol-buffers/docs/proto#services). A `Query` service should be created per module in `query.proto`. This service lists endpoints starting with `rpc`.
Here's an example of such a `Query` service definition:
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/auth/v1beta1/query.proto#L14-L89
```
As `proto.Message`s, generated `Response` types implement by default `String()` method of [`fmt.Stringer`](https://pkg.go.dev/fmt#Stringer).
A `RegisterQueryServer` method is also generated and should be used to register the module's query server in the `RegisterServices` method from the [`AppModule` interface](./01-module-manager.md#appmodule).
### Legacy Queries
Before the introduction of Protobuf and gRPC in the Cosmos SDK, there was usually no specific `query` object defined by module developers, contrary to `message`s. Instead, the Cosmos SDK took the simpler approach of using a simple `path` to define each `query`. The `path` contains the `query` type and all the arguments needed to process it. For most module queries, the `path` should look like the following:
```text
queryCategory/queryRoute/queryType/arg1/arg2/...
```
where:
* `queryCategory` is the category of the `query`, typically `custom` for module queries. It is used to differentiate between different kinds of queries within `BaseApp`'s [`Query` method](../../develop/advanced/00-baseapp.md#query).
* `queryRoute` is used by `BaseApp`'s [`queryRouter`](../../develop/advanced/00-baseapp.md#query-routing) to map the `query` to its module. Usually, `queryRoute` should be the name of the module.
* `queryType` is used by the module's [`querier`](./04-query-services.md#legacy-queriers) to map the `query` to the appropriate `querier function` within the module.
* `args` are the actual arguments needed to process the `query`. They are filled out by the end-user. Note that for bigger queries, you might prefer passing arguments in the `Data` field of the request `req` instead of the `path`.
The `path` for each `query` must be defined by the module developer in the module's [command-line interface file](./09-module-interfaces.md#query-commands).Overall, there are 3 mains components module developers need to implement in order to make the subset of the state defined by their module queryable:
* A [`querier`](./04-query-services.md#legacy-queriers), to process the `query` once it has been [routed to the module](../../develop/advanced/00-baseapp.md#query-routing).
* [Query commands](./09-module-interfaces.md#query-commands) in the module's CLI file, where the `path` for each `query` is specified.
* `query` return types. Typically defined in a file `types/querier.go`, they specify the result type of each of the module's `queries`. These custom types must implement the `String()` method of [`fmt.Stringer`](https://pkg.go.dev/fmt#Stringer).
### Store Queries
Store queries query directly for store keys. They use `clientCtx.QueryABCI(req abci.RequestQuery)` to return the full `abci.ResponseQuery` with inclusion Merkle proofs.
See following examples:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/abci.go#L864-L894
```
+119
View File
@@ -0,0 +1,119 @@
---
sidebar_position: 1
---
# `Msg` Services
:::note Synopsis
A Protobuf `Msg` service processes [messages](./02-messages-and-queries.md#messages). Protobuf `Msg` services are specific to the module in which they are defined, and only process messages defined within the said module. They are called from `BaseApp` during [`DeliverTx`](../../develop/advanced/00-baseapp.md#delivertx).
:::
:::note Pre-requisite Readings
* [Module Manager](./01-module-manager.md)
* [Messages and Queries](./02-messages-and-queries.md)
:::
## Implementation of a module `Msg` service
Each module should define a Protobuf `Msg` service, which will be responsible for processing requests (implementing `sdk.Msg`) and returning responses.
As further described in [ADR 031](../architecture/adr-031-msg-service.md), this approach has the advantage of clearly specifying return types and generating server and client code.
Protobuf generates a `MsgServer` interface based on a definition of `Msg` service. It is the role of the module developer to implement this interface, by implementing the state transition logic that should happen upon receival of each `sdk.Msg`. As an example, here is the generated `MsgServer` interface for `x/bank`, which exposes two `sdk.Msg`s:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/types/tx.pb.go#L550-L568
```
When possible, the existing module's [`Keeper`](./06-keeper.md) should implement `MsgServer`, otherwise a `msgServer` struct that embeds the `Keeper` can be created, typically in `./keeper/msg_server.go`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/msg_server.go#L17-L19
```
`msgServer` methods can retrieve the `context.Context` from the `context.Context` parameter method using the `sdk.UnwrapSDKContext`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/msg_server.go#L56
```
`sdk.Msg` processing usually follows these 3 steps:
### Validation
The message server must perform all validation required (both *stateful* and *stateless*) to make sure the `message` is valid.
The `signer` is charged for the gas cost of this validation.
For example, a `msgServer` method for a `transfer` message should check that the sending account has enough funds to actually perform the transfer.
It is recommended to implement all validation checks in a separate function that passes state values as arguments. This implementation simplifies testing. As expected, expensive validation functions charge additional gas. Example:
```go
ValidateMsgA(msg MsgA, now Time, gm GasMeter) error {
if now.Before(msg.Expire) {
return sdkerrrors.ErrInvalidRequest.Wrap("msg expired")
}
gm.ConsumeGas(1000, "signature verification")
return signatureVerificaton(msg.Prover, msg.Data)
}
```
:::warning
Previously, the `ValidateBasic` method was used to perform simple and stateless validation checks.
This way of validating is deprecated, this means the `msgServer` must perform all validation checks.
:::
### State Transition
After the validation is successful, the `msgServer` method uses the [`keeper`](./06-keeper.md) functions to access the state and perform a state transition.
### Events
Before returning, `msgServer` methods generally emit one or more [events](../../develop/advanced/08-events.md) by using the `EventManager` held in the `ctx`. Use the new `EmitTypedEvent` function that uses protobuf-based event types:
```go
ctx.EventManager().EmitTypedEvent(
&group.EventABC{Key1: Value1, Key2, Value2})
```
or the older `EmitEvent` function:
```go
ctx.EventManager().EmitEvent(
sdk.NewEvent(
eventType, // e.g. sdk.EventTypeMessage for a message, types.CustomEventType for a custom event defined in the module
sdk.NewAttribute(key1, value1),
sdk.NewAttribute(key2, value2),
),
)
```
These events are relayed back to the underlying consensus engine and can be used by service providers to implement services around the application. Click [here](../../develop/advanced/08-events.md) to learn more about events.
The invoked `msgServer` method returns a `proto.Message` response and an `error`. These return values are then wrapped into an `*sdk.Result` or an `error`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/baseapp/msg_service_router.go#L160
```
This method takes care of marshaling the `res` parameter to protobuf and attaching any events on the `ctx.EventManager()` to the `sdk.Result`.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/base/abci/v1beta1/abci.proto#L93-L113
```
This diagram shows a typical structure of a Protobuf `Msg` service, and how the message propagates through the module.
![Transaction flow](https://raw.githubusercontent.com/cosmos/cosmos-sdk/release/v0.46.x/docs/uml/svg/transaction_flow.svg)
## Telemetry
New [telemetry metrics](../../develop/advanced/09-telemetry.md) can be created from `msgServer` methods when handling messages.
This is an example from the `x/auth/vesting` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/vesting/msg_server.go#L76-L88
```
+57
View File
@@ -0,0 +1,57 @@
---
sidebar_position: 1
---
# Query Services
:::note Synopsis
A Protobuf Query service processes [`queries`](./02-messages-and-queries.md#queries). Query services are specific to the module in which they are defined, and only process `queries` defined within said module. They are called from `BaseApp`'s [`Query` method](../../develop/advanced/00-baseapp.md#query).
:::
:::note Pre-requisite Readings
* [Module Manager](./01-module-manager.md)
* [Messages and Queries](./02-messages-and-queries.md)
:::
## Implementation of a module query service
### gRPC Service
When defining a Protobuf `Query` service, a `QueryServer` interface is generated for each module with all the service methods:
```go
type QueryServer interface {
QueryBalance(context.Context, *QueryBalanceParams) (*types.Coin, error)
QueryAllBalances(context.Context, *QueryAllBalancesParams) (*QueryAllBalancesResponse, error)
}
```
These custom queries methods should be implemented by a module's keeper, typically in `./keeper/grpc_query.go`. The first parameter of these methods is a generic `context.Context`. Therefore, the Cosmos SDK provides a function `sdk.UnwrapSDKContext` to retrieve the `context.Context` from the provided
`context.Context`.
Here's an example implementation for the bank module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/grpc_query.go
```
### Calling queries from the State Machine
The Cosmos SDK v0.47 introduces a new `cosmos.query.v1.module_query_safe` Protobuf annotation which is used to state that a query that is safe to be called from within the state machine, for example:
* a Keeper's query function can be called from another module's Keeper,
* ADR-033 intermodule query calls,
* CosmWasm contracts can also directly interact with these queries.
If the `module_query_safe` annotation set to `true`, it means:
* The query is deterministic: given a block height it will return the same response upon multiple calls, and doesn't introduce any state-machine breaking changes across SDK patch versions.
* Gas consumption never fluctuates across calls and across patch versions.
If you are a module developer and want to use `module_query_safe` annotation for your own query, you have to ensure the following things:
* the query is deterministic and won't introduce state-machine-breaking changes without coordinated upgrades
* it has its gas tracked, to avoid the attack vector where no gas is accounted for
on potentially high-computation queries.
+121
View File
@@ -0,0 +1,121 @@
---
sidebar_position: 1
---
# ProtocolBuffer Annotations
This document explains the various protobuf scalars that have been added to make working with protobuf easier for Cosmos SDK application developers
## Signer
Signer specifies which field should be used to determine the signer of a message for the Cosmos SDK. This field can be used for clients as well to infer which field should be used to determine the signer of a message.
Read more about the signer field [here](./02-messages-and-queries.md).
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/e6848d99b55a65d014375b295bdd7f9641aac95e/proto/cosmos/bank/v1beta1/tx.proto#L40
```
```proto
option (cosmos.msg.v1.signer) = "from_address";
```
## Scalar
The scalar type defines a way for clients to understand how to construct protobuf messages according to what is expected by the module and sdk.
```proto
(cosmos_proto.scalar) = "cosmos.AddressString"
```
Example of account address string scalar:
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e6848d99b55a65d014375b295bdd7f9641aac95e/proto/cosmos/bank/v1beta1/tx.proto#L46
```
Example of validator address string scalar:
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/distribution/v1beta1/query.proto#L87
```
Example of Decimals scalar:
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/distribution/v1beta1/distribution.proto#L26
```
Example of Int scalar:
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/gov/v1/gov.proto#L137
```
There are a few options for what can be provided as a scalar: cosmos.AddressString, cosmos.ValidatorAddressString, cosmos.ConsensusAddressString, cosmos.Int, cosmos.Dec.
## Implements_Interface
Implement interface is used to provide information to client tooling like [telescope](https://github.com/cosmology-tech/telescope) on how to encode and decode protobuf messages.
```proto
option (cosmos_proto.implements_interface) = "cosmos.auth.v1beta1.AccountI";
```
## Amino
The amino codec was removed in 0.50.0, this means there is not a need register `legacyAminoCodec`. To replace the amino codec, Amino protobuf annotations are used to provide information to the amino codec on how to encode and decode protobuf messages.
:::note
Amino annotations are only used for backwards compatibility with amino. New modules are not required use amino annotations.
:::
The below annotations are used to provide information to the amino codec on how to encode and decode protobuf messages in a backwards compatible manner.
### Name
Name specifies the amino name that would show up for the user in order for them see which message they are signing.
```proto
option (amino.name) = "cosmos-sdk/BaseAccount";
```
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/bank/v1beta1/tx.proto#L41
```
### Field_Name
Field name specifies the amino name that would show up for the user in order for them see which field they are signing.
```proto
uint64 height = 1 [(amino.field_name) = "public_key"];
```
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/distribution/v1beta1/distribution.proto#L166
```
### Dont_OmitEmpty
Dont omitempty specifies that the field should not be omitted when encoding to amino.
```proto
repeated cosmos.base.v1beta1.Coin amount = 3 [(amino.dont_omitempty) = true];
```
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/bank/v1beta1/bank.proto#L56
```
### Encoding
Encoding specifies the amino encoding that should be used when encoding to amino.
```proto
(amino.encoding) = "legacy_coins",
```
```proto reference
https://github.com/cosmos/cosmos-sdk/blob/e8f28bf5db18b8d6b7e0d94b542ce4cf48fed9d6/proto/cosmos/bank/v1beta1/genesis.proto#L23
```
+47
View File
@@ -0,0 +1,47 @@
---
sidebar_position: 1
---
# BeginBlocker and EndBlocker
:::note Synopsis
`BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](../../develop/advanced/00-baseapp.md#beginblock) and [`EndBlock`](../../develop/advanced/00-baseapp.md#endblock) ABCI messages are received from the underlying consensus engine.
:::
:::note Pre-requisite Readings
* [Module Manager](./01-module-manager.md)
:::
## BeginBlocker and EndBlocker
`BeginBlocker` and `EndBlocker` are a way for module developers to add automatic execution of logic to their module. This is a powerful tool that should be used carefully, as complex automatic functions can slow down or even halt the chain.
In 0.47.0, Prepare and Process Proposal were added that allow app developers to do arbitrary work at those phases, but they do not influence the work that will be done in BeginBlock. If an application required `BeginBlock` to execute prior to any sort of work is done then this is not possible today (0.50.0).
When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`HasBeginBlocker`, `HasABCIEndBlocker` and `EndBlocker` interfaces](./01-module-manager.md#appmodule). This means either can be left-out if not required. The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in `abci.go`.
The actual implementation of `BeginBlocker` and `EndBlocker` in `abci.go` are very similar to that of a [`Msg` service](./03-msg-services.md):
* They generally use the [`keeper`](./06-keeper.md) and [`ctx`](../../develop/advanced/02-context.md) to retrieve information about the latest state.
* If needed, they use the `keeper` and `ctx` to trigger state-transitions.
* If needed, they can emit [`events`](../../develop/advanced/08-events.md) via the `ctx`'s `EventManager`.
A specific type of `EndBlocker` is available to return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](https://docs.cometbft.com/v0.37/spec/abci/abci++_methods#endblock). This is the preferred way to implement custom validator changes.
It is possible for developers to define the order of execution between the `BeginBlocker`/`EndBlocker` functions of each of their application's modules via the module's manager `SetOrderBeginBlocker`/`SetOrderEndBlocker` methods. For more on the module manager, click [here](./01-module-manager.md#manager).
See an example implementation of `BeginBlocker` from the `distribution` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/distribution/abci.go#L14-L38
```
and an example implementation of `EndBlocker` from the `staking` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/abci.go#L22-L27
```
<!-- TODO: leaving this here to update docs with core api changes -->
+92
View File
@@ -0,0 +1,92 @@
---
sidebar_position: 1
---
# Keepers
:::note Synopsis
`Keeper`s refer to a Cosmos SDK abstraction whose role is to manage access to the subset of the state defined by various modules. `Keeper`s are module-specific, i.e. the subset of state defined by a module can only be accessed by a `keeper` defined in said module. If a module needs to access the subset of state defined by another module, a reference to the second module's internal `keeper` needs to be passed to the first one. This is done in `app.go` during the instantiation of module keepers.
:::
:::note Pre-requisite Readings
* [Introduction to Cosmos SDK Modules](./00-intro.md)
:::
## Motivation
The Cosmos SDK is a framework that makes it easy for developers to build complex decentralized applications from scratch, mainly by composing modules together. As the ecosystem of open-source modules for the Cosmos SDK expands, it will become increasingly likely that some of these modules contain vulnerabilities, as a result of the negligence or malice of their developer.
The Cosmos SDK adopts an [object-capabilities-based approach](../../develop/advanced/10-ocap.md) to help developers better protect their application from unwanted inter-module interactions, and `keeper`s are at the core of this approach. A `keeper` can be considered quite literally to be the gatekeeper of a module's store(s). Each store (typically an [`IAVL` Store](../../develop/advanced/04-store.md#iavl-store)) defined within a module comes with a `storeKey`, which grants unlimited access to it. The module's `keeper` holds this `storeKey` (which should otherwise remain unexposed), and defines [methods](#implementing-methods) for reading and writing to the store(s).
The core idea behind the object-capabilities approach is to only reveal what is necessary to get the work done. In practice, this means that instead of handling permissions of modules through access-control lists, module `keeper`s are passed a reference to the specific instance of the other modules' `keeper`s that they need to access (this is done in the [application's constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function)). As a consequence, a module can only interact with the subset of state defined in another module via the methods exposed by the instance of the other module's `keeper`. This is a great way for developers to control the interactions that their own module can have with modules developed by external developers.
## Type Definition
`keeper`s are generally implemented in a `/keeper/keeper.go` file located in the module's folder. By convention, the type `keeper` of a module is simply named `Keeper` and usually follows the following structure:
```go
type Keeper struct {
// External keepers, if any
// Store key(s)
// codec
// authority
}
```
For example, here is the type definition of the `keeper` from the `staking` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keeper.go#L23-L31
```
Let us go through the different parameters:
* An expected `keeper` is a `keeper` external to a module that is required by the internal `keeper` of said module. External `keeper`s are listed in the internal `keeper`'s type definition as interfaces. These interfaces are themselves defined in an `expected_keepers.go` file in the root of the module's folder. In this context, interfaces are used to reduce the number of dependencies, as well as to facilitate the maintenance of the module itself.
* `storeKey`s grant access to the store(s) of the [multistore](../../develop/advanced/04-store.md) managed by the module. They should always remain unexposed to external modules.
* `cdc` is the [codec](../../develop/advanced/05-encoding.md) used to marshall and unmarshall structs to/from `[]byte`. The `cdc` can be any of `codec.BinaryCodec`, `codec.JSONCodec` or `codec.Codec` based on your requirements. It can be either a proto or amino codec as long as they implement these interfaces.
* The authority listed is a module account or user account that has the right to change module level parameters. Previously this was handled by the param module, which has been deprecated.
Of course, it is possible to define different types of internal `keeper`s for the same module (e.g. a read-only `keeper`). Each type of `keeper` comes with its own constructor function, which is called from the [application's constructor function](../../develop/beginner/00-app-anatomy.md). This is where `keeper`s are instantiated, and where developers make sure to pass correct instances of modules' `keeper`s to other modules that require them.
## Implementing Methods
`Keeper`s primarily expose getter and setter methods for the store(s) managed by their module. These methods should remain as simple as possible and strictly be limited to getting or setting the requested value, as validity checks should have already been performed by the [`Msg` server](./03-msg-services.md) when `keeper`s' methods are called.
Typically, a *getter* method will have the following signature
```go
func (k Keeper) Get(ctx context.Context, key string) returnType
```
and the method will go through the following steps:
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`. Then it's preferred to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
2. If it exists, get the `[]byte` value stored at location `[]byte(key)` using the `Get(key []byte)` method of the store.
3. Unmarshall the retrieved value from `[]byte` to `returnType` using the codec `cdc`. Return the value.
Similarly, a *setter* method will have the following signature
```go
func (k Keeper) Set(ctx context.Context, key string, value valueType)
```
and the method will go through the following steps:
1. Retrieve the appropriate store from the `ctx` using the `storeKey`. This is done through the `KVStore(storeKey sdk.StoreKey)` method of the `ctx`. It's preferred to use the `prefix.Store` to access only the desired limited subset of the store for convenience and safety.
2. Marshal `value` to `[]byte` using the codec `cdc`.
3. Set the encoded value in the store at location `key` using the `Set(key []byte, value []byte)` method of the store.
For more, see an example of `keeper`'s [methods implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/keeper.go).
The [module `KVStore`](../../develop/advanced/04-store.md#kvstore-and-commitkvstore-interfaces) also provides an `Iterator()` method which returns an `Iterator` object to iterate over a domain of keys.
This is an example from the `auth` module to iterate accounts:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/account.go
```
+90
View File
@@ -0,0 +1,90 @@
---
sidebar_position: 1
---
# Invariants
:::note Synopsis
An invariant is a property of the application that should always be true. In the context of the Cosmos SDK, an `Invariant` is a function that checks for a particular invariant. These functions are useful to detect bugs early on and act upon them to limit their potential consequences (e.g. by halting the chain). They are also useful in the development process of the application to detect bugs via simulations.
:::
:::note Pre-requisite Readings
* [Keepers](./06-keeper.md)
:::
## Implementing `Invariant`s
An `Invariant` is a function that checks for a particular invariant within a module. Module `Invariant`s must follow the `Invariant` type:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/invariant.go#L9
```
The `string` return value is the invariant message, which can be used when printing logs, and the `bool` return value is the actual result of the invariant check.
In practice, each module implements `Invariant`s in a `keeper/invariants.go` file within the module's folder. The standard is to implement one `Invariant` function per logical grouping of invariants with the following model:
```go
// Example for an Invariant that checks balance-related invariants
func BalanceInvariants(k Keeper) sdk.Invariant {
return func(ctx context.Context) (string, bool) {
// Implement checks for balance-related invariants
}
}
```
Additionally, module developers should generally implement an `AllInvariants` function that runs all the `Invariant`s functions of the module:
```go
// AllInvariants runs all invariants of the module.
// In this example, the module implements two Invariants: BalanceInvariants and DepositsInvariants
func AllInvariants(k Keeper) sdk.Invariant {
return func(ctx context.Context) (string, bool) {
res, stop := BalanceInvariants(k)(ctx)
if stop {
return res, stop
}
return DepositsInvariant(k)(ctx)
}
}
```
Finally, module developers need to implement the `RegisterInvariants` method as part of the [`AppModule` interface](./01-module-manager.md#appmodule). Indeed, the `RegisterInvariants` method of the module, implemented in the `module/module.go` file, typically only defers the call to a `RegisterInvariants` method implemented in the `keeper/invariants.go` file. The `RegisterInvariants` method registers a route for each `Invariant` function in the [`InvariantRegistry`](#invariant-registry):
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/invariants.go#L12-L22
```
For more, see an example of [`Invariant`s implementation from the `staking` module](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/staking/keeper/invariants.go).
## Invariant Registry
The `InvariantRegistry` is a registry where the `Invariant`s of all the modules of an application are registered. There is only one `InvariantRegistry` per **application**, meaning module developers need not implement their own `InvariantRegistry` when building a module. **All module developers need to do is to register their modules' invariants in the `InvariantRegistry`, as explained in the section above**. The rest of this section gives more information on the `InvariantRegistry` itself, and does not contain anything directly relevant to module developers.
At its core, the `InvariantRegistry` is defined in the Cosmos SDK as an interface:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/types/invariant.go#L14-L17
```
Typically, this interface is implemented in the `keeper` of a specific module. The most used implementation of an `InvariantRegistry` can be found in the `crisis` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/crisis/keeper/keeper.go#L48-L50
```
The `InvariantRegistry` is therefore typically instantiated by instantiating the `keeper` of the `crisis` module in the [application's constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
`Invariant`s can be checked manually via [`message`s](./02-messages-and-queries.md), but most often they are checked automatically at the end of each block. Here is an example from the `crisis` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/crisis/abci.go#L13-L23
```
In both cases, if one of the `Invariant`s returns false, the `InvariantRegistry` can trigger special logic (e.g. have the application panic and print the `Invariant`s message in the log).
+78
View File
@@ -0,0 +1,78 @@
---
sidebar_position: 1
---
# Module Genesis
:::note Synopsis
Modules generally handle a subset of the state and, as such, they need to define the related subset of the genesis file as well as methods to initialize, verify and export it.
:::
:::note Pre-requisite Readings
* [Module Manager](./01-module-manager.md)
* [Keepers](./06-keeper.md)
:::
## Type Definition
The subset of the genesis state defined from a given module is generally defined in a `genesis.proto` file ([more info](../../develop/advanced/05-encoding.md#gogoproto) on how to define protobuf messages). The struct defining the module's subset of the genesis state is usually called `GenesisState` and contains all the module-related values that need to be initialized during the genesis process.
See an example of `GenesisState` protobuf message definition from the `auth` module:
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/auth/v1beta1/genesis.proto
```
Next we present the main genesis-related methods that need to be implemented by module developers in order for their module to be used in Cosmos SDK applications.
### `DefaultGenesis`
The `DefaultGenesis()` method is a simple method that calls the constructor function for `GenesisState` with the default value for each parameter. See an example from the `auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/module.go#L63-L67
```
### `ValidateGenesis`
The `ValidateGenesis(data GenesisState)` method is called to verify that the provided `genesisState` is correct. It should perform validity checks on each of the parameters listed in `GenesisState`. See an example from the `auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/types/genesis.go#L62-L75
```
## Other Genesis Methods
Other than the methods related directly to `GenesisState`, module developers are expected to implement two other methods as part of the [`AppModuleGenesis` interface](./01-module-manager.md#appmodulegenesis) (only if the module needs to initialize a subset of state in genesis). These methods are [`InitGenesis`](#initgenesis) and [`ExportGenesis`](#exportgenesis).
### `InitGenesis`
The `InitGenesis` method is executed during [`InitChain`](../../develop/advanced/00-baseapp.md#initchain) when the application is first started. Given a `GenesisState`, it initializes the subset of the state managed by the module by using the module's [`keeper`](./06-keeper.md) setter function on each parameter within the `GenesisState`.
The [module manager](./01-module-manager.md#manager) of the application is responsible for calling the `InitGenesis` method of each of the application's modules in order. This order is set by the application developer via the manager's `SetOrderGenesisMethod`, which is called in the [application's constructor function](../../develop/beginner/00-app-anatomy.md#constructor-function).
See an example of `InitGenesis` from the `auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/genesis.go#L8-L35
```
### `ExportGenesis`
The `ExportGenesis` method is executed whenever an export of the state is made. It takes the latest known version of the subset of the state managed by the module and creates a new `GenesisState` out of it. This is mainly used when the chain needs to be upgraded via a hard fork.
See an example of `ExportGenesis` from the `auth` module.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/keeper/genesis.go#L37-L49
```
### GenesisTxHandler
`GenesisTxHandler` is a way for modules to submit state transitions prior to the first block. This is used by `x/genutil` to submit the genesis transactions for the validators to be added to staking.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/core/genesis/txhandler.go#L3-L6
```
+164
View File
@@ -0,0 +1,164 @@
---
sidebar_position: 1
---
# Module Interfaces
:::note Synopsis
This document details how to build CLI and REST interfaces for a module. Examples from various Cosmos SDK modules are included.
:::
:::note Pre-requisite Readings
* [Building Modules Intro](./00-intro.md)
:::
## CLI
One of the main interfaces for an application is the [command-line interface](../../develop/advanced/07-cli.md). This entrypoint adds commands from the application's modules enabling end-users to create [**messages**](./02-messages-and-queries.md#messages) wrapped in transactions and [**queries**](./02-messages-and-queries.md#queries). The CLI files are typically found in the module's `./client/cli` folder.
### Transaction Commands
In order to create messages that trigger state changes, end-users must create [transactions](../../develop/advanced/01-transactions.md) that wrap and deliver the messages. A transaction command creates a transaction that includes one or more messages.
Transaction commands typically have their own `tx.go` file that lives within the module's `./client/cli` folder. The commands are specified in getter functions and the name of the function should include the name of the command.
Here is an example from the `x/bank` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/client/cli/tx.go#L37-L76
```
In the example, `NewSendTxCmd()` creates and returns the transaction command for a transaction that wraps and delivers `MsgSend`. `MsgSend` is the message used to send tokens from one account to another.
In general, the getter function does the following:
* **Constructs the command:** Read the [Cobra Documentation](https://pkg.go.dev/github.com/spf13/cobra) for more detailed information on how to create commands.
* **Use:** Specifies the format of the user input required to invoke the command. In the example above, `send` is the name of the transaction command and `[from_key_or_address]`, `[to_address]`, and `[amount]` are the arguments.
* **Args:** The number of arguments the user provides. In this case, there are exactly three: `[from_key_or_address]`, `[to_address]`, and `[amount]`.
* **Short and Long:** Descriptions for the command. A `Short` description is expected. A `Long` description can be used to provide additional information that is displayed when a user adds the `--help` flag.
* **RunE:** Defines a function that can return an error. This is the function that is called when the command is executed. This function encapsulates all of the logic to create a new transaction.
* The function typically starts by getting the `clientCtx`, which can be done with `client.GetClientTxContext(cmd)`. The `clientCtx` contains information relevant to transaction handling, including information about the user. In this example, the `clientCtx` is used to retrieve the address of the sender by calling `clientCtx.GetFromAddress()`.
* If applicable, the command's arguments are parsed. In this example, the arguments `[to_address]` and `[amount]` are both parsed.
* A [message](./02-messages-and-queries.md) is created using the parsed arguments and information from the `clientCtx`. The constructor function of the message type is called directly. In this case, `types.NewMsgSend(fromAddr, toAddr, amount)`. Its good practice to call, if possible, the necessary [message validation methods](../building-modules/03-msg-services.md#Validation) before broadcasting the message.
* Depending on what the user wants, the transaction is either generated offline or signed and broadcasted to the preconfigured node using `tx.GenerateOrBroadcastTxCLI(clientCtx, flags, msg)`.
* **Adds transaction flags:** All transaction commands must add a set of transaction [flags](#flags). The transaction flags are used to collect additional information from the user (e.g. the amount of fees the user is willing to pay). The transaction flags are added to the constructed command using `AddTxFlagsToCmd(cmd)`.
* **Returns the command:** Finally, the transaction command is returned.
Each module can implement `NewTxCmd()`, which aggregates all of the transaction commands of the module. Here is an example from the `x/bank` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/client/cli/tx.go#L20-L35
```
Each module then can also implement a `GetTxCmd()` method that simply returns `NewTxCmd()`. This allows the root command to easily aggregate all of the transaction commands for each module. Here is an example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/module.go#L84-L86
```
### Query Commands
:::warning
This section is being rewritten. Refer to [AutoCLI](https://docs.cosmos.network/main/core/autocli) while this section is being updated.
:::
<!-- UPDATE THIS TO AUTOCLI
[Queries](./02-messages-and-queries.md#queries) allow users to gather information about the application or network state; they are routed by the application and processed by the module in which they are defined. Query commands typically have their own `query.go` file in the module's `./client/cli` folder. Like transaction commands, they are specified in getter functions. Here is an example of a query command from the `x/auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/client/cli/query.go#L86-L128
```
In the example, `GetAccountCmd()` creates and returns a query command that returns the state of an account based on the provided account address.
In general, the getter function does the following:
* **Constructs the command:** Read the [Cobra Documentation](https://pkg.go.dev/github.com/spf13/cobra) for more detailed information on how to create commands.
* **Use:** Specifies the format of the user input required to invoke the command. In the example above, `account` is the name of the query command and `[address]` is the argument.
* **Args:** The number of arguments the user provides. In this case, there is exactly one: `[address]`.
* **Short and Long:** Descriptions for the command. A `Short` description is expected. A `Long` description can be used to provide additional information that is displayed when a user adds the `--help` flag.
* **RunE:** Defines a function that can return an error. This is the function that is called when the command is executed. This function encapsulates all of the logic to create a new query.
* The function typically starts by getting the `clientCtx`, which can be done with `client.GetClientQueryContext(cmd)`. The `clientCtx` contains information relevant to query handling.
* If applicable, the command's arguments are parsed. In this example, the argument `[address]` is parsed.
* A new `queryClient` is initialized using `NewQueryClient(clientCtx)`. The `queryClient` is then used to call the appropriate [query](./02-messages-and-queries.md#grpc-queries).
* The `clientCtx.PrintProto` method is used to format the `proto.Message` object so that the results can be printed back to the user.
* **Adds query flags:** All query commands must add a set of query [flags](#flags). The query flags are added to the constructed command using `AddQueryFlagsToCmd(cmd)`.
* **Returns the command:** Finally, the query command is returned.
Each module must implement `GetQueryCmd()`, which aggregates all of the query commands of the module. Here is an example from the `x/auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/client/cli/query.go#L33-L53
```
Each module must also implement the `GetQueryCmd()` method for `AppModuleBasic` that returns the `GetQueryCmd()` function. This allows for the root command to easily aggregate all of the query commands for each module. Here is an example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/module.go#L84-L87
```
### Flags
[Flags](../../develop/advanced/07-cli.md#flags) allow users to customize commands. `--fees` and `--gas-prices` are examples of flags that allow users to set the [fees](../../develop/beginner/04-gas-fees.md) and gas prices for their transactions.
Flags that are specific to a module are typically created in a `flags.go` file in the module's `./client/cli` folder. When creating a flag, developers set the value type, the name of the flag, the default value, and a description about the flag. Developers also have the option to mark flags as _required_ so that an error is thrown if the user does not include a value for the flag.
Here is an example that adds the `--from` flag to a command:
```go
cmd.Flags().String(FlagFrom, "", "Name or address of private key with which to sign")
```
In this example, the value of the flag is a `String`, the name of the flag is `from` (the value of the `FlagFrom` constant), the default value of the flag is `""`, and there is a description that will be displayed when a user adds `--help` to the command.
Here is an example that marks the `--from` flag as _required_:
```go
cmd.MarkFlagRequired(FlagFrom)
```
For more detailed information on creating flags, visit the [Cobra Documentation](https://github.com/spf13/cobra).
As mentioned in [transaction commands](#transaction-commands), there is a set of flags that all transaction commands must add. This is done with the `AddTxFlagsToCmd` method defined in the Cosmos SDK's `./client/flags` package.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/flags/flags.go#L108-L138
```
Since `AddTxFlagsToCmd(cmd *cobra.Command)` includes all of the basic flags required for a transaction command, module developers may choose not to add any of their own (specifying arguments instead may often be more appropriate).
Similarly, there is a `AddQueryFlagsToCmd(cmd *cobra.Command)` to add common flags to a module query command.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/client/flags/flags.go#L95-L106```
-->
## gRPC
[gRPC](https://grpc.io/) is a Remote Procedure Call (RPC) framework. RPC is the preferred way for external clients like wallets and exchanges to interact with a blockchain.
In addition to providing an ABCI query pathway, the Cosmos SDK provides a gRPC proxy server that routes gRPC query requests to ABCI query requests.
In order to do that, modules must implement `RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)` on `AppModuleBasic` to wire the client gRPC requests to the correct handler inside the module.
Here's an example from the `x/auth` module:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/auth/module.go#L71-L76
```
## gRPC-gateway REST
Applications need to support web services that use HTTP requests (e.g. a web wallet like [Keplr](https://keplr.app)). [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) translates REST calls into gRPC calls, which might be useful for clients that do not use gRPC.
Modules that want to expose REST queries should add `google.api.http` annotations to their `rpc` methods, such as in the example below from the `x/auth` module:
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/auth/v1beta1/query.proto#L14-L89
```
gRPC gateway is started in-process along with the application and CometBFT. It can be enabled or disabled by setting gRPC Configuration `enable` in [`app.toml`](../run-node/01-run-node.md#configuring-the-node-using-apptoml-and-configtoml).
The Cosmos SDK provides a command for generating [Swagger](https://swagger.io/) documentation (`protoc-gen-swagger`). Setting `swagger` in [`app.toml`](../run-node/01-run-node.md#configuring-the-node-using-apptoml-and-configtoml) defines if swagger documentation should be automatically registered.
+95
View File
@@ -0,0 +1,95 @@
---
sidebar_position: 1
---
# Recommended Folder Structure
:::note Synopsis
This document outlines the recommended structure of Cosmos SDK modules. These ideas are meant to be applied as suggestions. Application developers are encouraged to improve upon and contribute to module structure and development design.
:::
## Structure
A typical Cosmos SDK module can be structured as follows:
```shell
proto
└── {project_name}
   └── {module_name}
   └── {proto_version}
      ├── {module_name}.proto
      ├── event.proto
      ├── genesis.proto
      ├── query.proto
      └── tx.proto
```
* `{module_name}.proto`: The module's common message type definitions.
* `event.proto`: The module's message type definitions related to events.
* `genesis.proto`: The module's message type definitions related to genesis state.
* `query.proto`: The module's Query service and related message type definitions.
* `tx.proto`: The module's Msg service and related message type definitions.
```shell
x/{module_name}
├── client
│   ├── cli
│   │ ├── query.go
│   │   └── tx.go
│   └── testutil
│   ├── cli_test.go
│   └── suite.go
├── exported
│   └── exported.go
├── keeper
│   ├── genesis.go
│   ├── grpc_query.go
│   ├── hooks.go
│   ├── invariants.go
│   ├── keeper.go
│   ├── keys.go
│   ├── msg_server.go
│   └── querier.go
├── module
│   └── module.go
│   └── abci.go
│   └── autocli.go
├── simulation
│   ├── decoder.go
│   ├── genesis.go
│   ├── operations.go
│   └── params.go
├── {module_name}.pb.go
├── codec.go
├── errors.go
├── events.go
├── events.pb.go
├── expected_keepers.go
├── genesis.go
├── genesis.pb.go
├── keys.go
├── msgs.go
├── params.go
├── query.pb.go
├── tx.pb.go
└── README.md
```
* `client/`: The module's CLI client functionality implementation and the module's CLI testing suite.
* `exported/`: The module's exported types - typically interface types. If a module relies on keepers from another module, it is expected to receive the keepers as interface contracts through the `expected_keepers.go` file (see below) in order to avoid a direct dependency on the module implementing the keepers. However, these interface contracts can define methods that operate on and/or return types that are specific to the module that is implementing the keepers and this is where `exported/` comes into play. The interface types that are defined in `exported/` use canonical types, allowing for the module to receive the keepers as interface contracts through the `expected_keepers.go` file. This pattern allows for code to remain DRY and also alleviates import cycle chaos.
* `keeper/`: The module's `Keeper` and `MsgServer` implementation.
* `module/`: The module's `AppModule` and `AppModuleBasic` implementation.
* `abci.go`: The module's `BeginBlocker` and `EndBlocker` implementations (this file is only required if `BeginBlocker` and/or `EndBlocker` need to be defined).
* `autocli.go`: The module [autocli](https://docs.cosmos.network/main/core/autocli) options.
* `simulation/`: The module's [simulation](./14-simulator.md) package defines functions used by the blockchain simulator application (`simapp`).
* `README.md`: The module's specification documents outlining important concepts, state storage structure, and message and event type definitions. Learn more how to write module specs in the [spec guidelines](../spec/SPEC_MODULE.md).
* The root directory includes type definitions for messages, events, and genesis state, including the type definitions generated by Protocol Buffers.
* `codec.go`: The module's registry methods for interface types.
* `errors.go`: The module's sentinel errors.
* `events.go`: The module's event types and constructors.
* `expected_keepers.go`: The module's [expected keeper](./06-keeper.md#type-definition) interfaces.
* `genesis.go`: The module's genesis state methods and helper functions.
* `keys.go`: The module's store keys and associated helper functions.
* `msgs.go`: The module's message type definitions and associated methods.
* `params.go`: The module's parameter type definitions and associated methods.
* `*.pb.go`: The module's type definitions generated by Protocol Buffers (as defined in the respective `*.proto` files above).
+56
View File
@@ -0,0 +1,56 @@
---
sidebar_position: 1
---
# Errors
:::note Synopsis
This document outlines the recommended usage and APIs for error handling in Cosmos SDK modules.
:::
Modules are encouraged to define and register their own errors to provide better
context on failed message or handler execution. Typically, these errors should be
common or general errors which can be further wrapped to provide additional specific
execution context.
## Registration
Modules should define and register their custom errors in `x/{module}/errors.go`.
Registration of errors is handled via the [`errors` package](https://github.com/cosmos/cosmos-sdk/blob/main/errors/errors.go).
Example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/distribution/types/errors.go
```
Each custom module error must provide the codespace, which is typically the module name
(e.g. "distribution") and is unique per module, and a uint32 code. Together, the codespace and code
provide a globally unique Cosmos SDK error. Typically, the code is monotonically increasing but does not
necessarily have to be. The only restrictions on error codes are the following:
* Must be greater than one, as a code value of one is reserved for internal errors.
* Must be unique within the module.
Note, the Cosmos SDK provides a core set of *common* errors. These errors are defined in [`types/errors/errors.go`](https://github.com/cosmos/cosmos-sdk/blob/main/types/errors/errors.go).
## Wrapping
The custom module errors can be returned as their concrete type as they already fulfill the `error`
interface. However, module errors can be wrapped to provide further context and meaning to failed
execution.
Example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/keeper.go#L141-L182
```
Regardless if an error is wrapped or not, the Cosmos SDK's `errors` package provides a function to determine if
an error is of a particular kind via `Is`.
## ABCI
If a module error is registered, the Cosmos SDK `errors` package allows ABCI information to be extracted
through the `ABCIInfo` function. The package also provides `ResponseCheckTx` and `ResponseDeliverTx` as
auxiliary functions to automatically get `CheckTx` and `DeliverTx` responses from an error.
+63
View File
@@ -0,0 +1,63 @@
---
sidebar_position: 1
---
# Upgrading Modules
:::note Synopsis
[In-Place Store Migrations](../../develop/advanced/15-upgrade.md) allow your modules to upgrade to new versions that include breaking changes. This document outlines how to build modules to take advantage of this functionality.
:::
:::note Pre-requisite Readings
* [In-Place Store Migration](../../develop/advanced/15-upgrade.md)
:::
## Consensus Version
Successful upgrades of existing modules require each `AppModule` to implement the function `ConsensusVersion() uint64`.
* The versions must be hard-coded by the module developer.
* The initial version **must** be set to 1.
Consensus versions serve as state-breaking versions of app modules and must be incremented when the module introduces breaking changes.
## Registering Migrations
To register the functionality that takes place during a module upgrade, you must register which migrations you want to take place.
Migration registration takes place in the `Configurator` using the `RegisterMigration` method. The `AppModule` reference to the configurator is in the `RegisterServices` method.
You can register one or more migrations. If you register more than one migration script, list the migrations in increasing order and ensure there are enough migrations that lead to the desired consensus version. For example, to migrate to version 3 of a module, register separate migrations for version 1 and version 2 as shown in the following example:
```go
func (am AppModule) RegisterServices(cfg module.Configurator) {
// --snip--
cfg.RegisterMigration(types.ModuleName, 1, func(ctx sdk.Context) error {
// Perform in-place store migrations from ConsensusVersion 1 to 2.
})
cfg.RegisterMigration(types.ModuleName, 2, func(ctx sdk.Context) error {
// Perform in-place store migrations from ConsensusVersion 2 to 3.
})
}
```
Since these migrations are functions that need access to a Keeper's store, use a wrapper around the keepers called `Migrator` as shown in this example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/keeper/migrations.go
```
## Writing Migration Scripts
To define the functionality that takes place during an upgrade, write a migration script and place the functions in a `migrations/` directory. For example, to write migration scripts for the bank module, place the functions in `x/bank/migrations/`. Use the recommended naming convention for these functions. For example, `v2bank` is the script that migrates the package `x/bank/migrations/v2`:
```go
// Migrating bank module from version 1 to 2
func (m Migrator) Migrate1to2(ctx sdk.Context) error {
return v2bank.MigrateStore(ctx, m.keeper.storeKey) // v2bank is package `x/bank/migrations/v2`.
}
```
To see example code of changes that were implemented in a migration of balance keys, check out [migrateBalanceKeys](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/bank/migrations/v2/store.go#L55-L76). For context, this code introduced migrations of the bank store that updated addresses to be prefixed by their length in bytes as outlined in [ADR-028](../architecture/adr-028-public-key-addresses.md).
+133
View File
@@ -0,0 +1,133 @@
---
sidebar_position: 1
---
# Module Simulation
:::note Pre-requisite Readings
* [Cosmos Blockchain Simulator](../../develop/advanced/12-simulation.md)
:::
## Synopsis
This document details how to define each module simulation functions to be
integrated with the application `SimulationManager`.
* [Simulation package](#simulation-package)
* [Store decoders](#store-decoders)
* [Randomized genesis](#randomized-genesis)
* [Randomized parameter changes](#randomized-parameter-changes)
* [Random weighted operations](#random-weighted-operations)
* [Random proposal contents](#random-proposal-contents)
* [Registering simulation functions](#registering-simulation-functions)
* [App Simulator manager](#app-simulator-manager)
## Simulation package
Every module that implements the Cosmos SDK simulator needs to have a `x/<module>/simulation`
package which contains the primary functions required by the fuzz tests: store
decoders, randomized genesis state and parameters, weighted operations and proposal
contents.
### Store decoders
Registering the store decoders is required for the `AppImportExport`. This allows
for the key-value pairs from the stores to be decoded (_i.e_ unmarshalled)
to their corresponding types. In particular, it matches the key to a concrete type
and then unmarshals the value from the `KVPair` to the type provided.
You can use the example [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/distribution/simulation/decoder.go) from the distribution module to implement your store decoders.
### Randomized genesis
The simulator tests different scenarios and values for genesis parameters
in order to fully test the edge cases of specific modules. The `simulator` package from each module must expose a `RandomizedGenState` function to generate the initial random `GenesisState` from a given seed.
Once the module genesis parameter are generated randomly (or with the key and
values defined in a `params` file), they are marshaled to JSON format and added
to the app genesis JSON to use it on the simulations.
You can check an example on how to create the randomized genesis [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/genesis.go).
### Randomized parameter changes
The simulator is able to test parameter changes at random. The simulator package from each module must contain a `RandomizedParams` func that will simulate parameter changes of the module throughout the simulations lifespan.
You can see how an example of what is needed to fully test parameter changes [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/params.go)
### Random weighted operations
Operations are one of the crucial parts of the Cosmos SDK simulation. They are the transactions
(`Msg`) that are simulated with random field values. The sender of the operation
is also assigned randomly.
Operations on the simulation are simulated using the full [transaction cycle](../../develop/advanced/01-transactions.md) of a
`ABCI` application that exposes the `BaseApp`.
Shown below is how weights are set:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/operations.go#L19-L86
```
As you can see, the weights are predefined in this case. Options exist to override this behavior with different weights. One option is to use `*rand.Rand` to define a random weight for the operation, or you can inject your own predefined weights.
Here is how one can override the above package `simappparams`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v/Makefile#L293-L299
```
For the last test a tool called [runsim](https://github.com/cosmos/tools/tree/master/cmd/runsim) is used, this is used to parallelize go test instances, provide info to Github and slack integrations to provide information to your team on how the simulations are running.
### Random proposal contents
Randomized governance proposals are also supported on the Cosmos SDK simulator. Each
module must define the governance proposal `Content`s that they expose and register
them to be used on the parameters.
## Registering simulation functions
Now that all the required functions are defined, we need to integrate them into the module pattern within the `module.go`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v/x/distribution/module.go#L180-L203
```
## App Simulator manager
The following step is setting up the `SimulatorManager` at the app level. This
is required for the simulation test files on the next step.
```go
type CustomApp struct {
...
sm *module.SimulationManager
}
```
Then at the instantiation of the application, we create the `SimulationManager`
instance in the same way we create the `ModuleManager` but this time we only pass
the modules that implement the simulation functions from the `AppModuleSimulation`
interface described above.
```go
func NewCustomApp(...) {
// create the simulation manager and define the order of the modules for deterministic simulations
app.sm = module.NewSimulationManager(
auth.NewAppModule(app.accountKeeper),
bank.NewAppModule(app.bankKeeper, app.accountKeeper),
supply.NewAppModule(app.supplyKeeper, app.accountKeeper),
gov.NewAppModule(app.govKeeper, app.accountKeeper, app.supplyKeeper),
mint.NewAppModule(app.mintKeeper),
distr.NewAppModule(app.distrKeeper, app.accountKeeper, app.supplyKeeper, app.stakingKeeper),
staking.NewAppModule(app.stakingKeeper, app.accountKeeper, app.supplyKeeper),
slashing.NewAppModule(app.slashingKeeper, app.accountKeeper, app.stakingKeeper),
)
// register the store decoders for simulation tests
app.sm.RegisterStoreDecoders()
...
}
```
+124
View File
@@ -0,0 +1,124 @@
---
sidebar_position: 1
---
# Modules depinject-ready
:::note Pre-requisite Readings
* [Depinject Documentation](../packages/01-depinject.md)
:::
[`depinject`](../packages/01-depinject.md) is used to wire any module in `app.go`.
All core modules are already configured to support dependency injection.
To work with `depinject` a module must define its configuration and requirements so that `depinject` can provide the right dependencies.
In brief, as a module developer, the following steps are required:
1. Define the module configuration using Protobuf
2. Define the module dependencies in `x/{moduleName}/module.go`
A chain developer can then use the module by following these two steps:
1. Configure the module in `app_config.go` or `app.yaml`
2. Inject the module in `app.go`
## Module Configuration
The module available configuration is defined in a Protobuf file, located at `{moduleName}/module/v1/module.proto`.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/group/module/v1/module.proto
```
* `go_import` must point to the Go package of the custom module.
* Message fields define the module configuration.
That configuration can be set in the `app_config.go` / `app.yaml` file for a chain developer to configure the module.
Taking `group` as example, a chain developer is able to decide, thanks to `uint64 max_metadata_len`, what the maximum metadata length allowed for a group proposal is.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L228-L234
```
That message is generated using [`pulsar`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/scripts/protocgen-pulsar.sh) (by running `make proto-gen`).
In the case of the `group` module, this file is generated here: https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/api/cosmos/group/module/v1/module.pulsar.go.
The part that is relevant for the module configuration is:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/api/cosmos/group/module/v1/module.pulsar.go#L515-L527
```
:::note
Pulsar is optional. The official [`protoc-gen-go`](https://developers.google.com/protocol-buffers/docs/reference/go-generated) can be used as well.
:::
## Dependency Definition
Once the configuration proto is defined, the module's `module.go` must define what dependencies are required by the module.
The boilerplate is similar for all modules.
:::warning
All methods, structs and their fields must be public for `depinject`.
:::
1. Import the module configuration generated package:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L12-L14
```
Define an `init()` function for defining the `providers` of the module configuration:
This registers the module configuration message and the wiring of the module.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L194-L199
```
2. Ensure that the module implements the `appmodule.AppModule` interface:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0/x/group/module/module.go#L58-L64
```
3. Define a struct that inherits `depinject.In` and define the module inputs (i.e. module dependencies):
* `depinject` provides the right dependencies to the module.
* `depinject` also checks that all dependencies are provided.
:::tip
For making a dependency optional, add the `optional:"true"` struct tag.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L201-L211
```
4. Define the module outputs with a public struct that inherits `depinject.Out`:
The module outputs are the dependencies that the module provides to other modules. It is usually the module itself and its keeper.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L213-L218
```
5. Create a function named `ProvideModule` (as called in 1.) and use the inputs for instantiating the module outputs.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L220-L235
```
The `ProvideModule` function should return an instance of `cosmossdk.io/core/appmodule.AppModule` which implements
one or more app module extension interfaces for initializing the module.
Following is the complete app wiring configuration for `group`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L194-L235
```
The module is now ready to be used with `depinject` by a chain developer.
## Integrate in an application
The App Wiring is done in `app_config.go` / `app.yaml` and `app_v2.go` and is explained in detail in the [overview of `app_v2.go`](../building-apps/01-app-go-v2.md).
+124
View File
@@ -0,0 +1,124 @@
---
sidebar_position: 1
---
# Testing
The Cosmos SDK contains different types of [tests](https://martinfowler.com/articles/practical-test-pyramid.html).
These tests have different goals and are used at different stages of the development cycle.
We advice, as a general rule, to use tests at all stages of the development cycle.
It is adviced, as a chain developer, to test your application and modules in a similar way than the SDK.
The rationale behind testing can be found in [ADR-59](https://docs.cosmos.network/main/architecture/adr-059-test-scopes.html).
## Unit Tests
Unit tests are the lowest test category of the [test pyramid](https://martinfowler.com/articles/practical-test-pyramid.html).
All packages and modules should have unit test coverage. Modules should have their dependencies mocked: this means mocking keepers.
The SDK uses `mockgen` to generate mocks for keepers:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/scripts/mockgen.sh#L3-L6
```
You can read more about mockgen [here](https://github.com/golang/mock).
### Example
As an example, we will walkthrough the [keeper tests](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/keeper/keeper_test.go) of the `x/gov` module.
The `x/gov` module has a `Keeper` type, which requires a few external dependencies (ie. imports outside `x/gov` to work properly).
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/keeper/keeper.go#L22-L24
```
In order to only test `x/gov`, we mock the [expected keepers](https://docs.cosmos.network/v0.46/building-modules/keeper.html#type-definition) and instantiate the `Keeper` with the mocked dependencies. Note that we may need to configure the mocked dependencies to return the expected values:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/keeper/common_test.go#L67-L81
```
This allows us to test the `x/gov` module without having to import other modules.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/keeper/keeper_test.go#L3-L42
```
We can test then create unit tests using the newly created `Keeper` instance.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/keeper/keeper_test.go#L83-L107
```
## Integration Tests
Integration tests are at the second level of the [test pyramid](https://martinfowler.com/articles/practical-test-pyramid.html).
In the SDK, we locate our integration tests under [`/tests/integrations`](https://github.com/cosmos/cosmos-sdk/tree/main/tests/integration).
The goal of these integration tests is to test how a component interacts with other dependencies. Compared to unit tests, integration tests do not mock dependencies. Instead, they use the direct dependencies of the component. This differs as well from end-to-end tests, which test the component with a full application.
Integration tests interact with the tested module via the defined `Msg` and `Query` services. The result of the test can be verified by checking the state of the application, by checking the emitted events or the response. It is adviced to combine two of these methods to verify the result of the test.
The SDK provides small helpers for quickly setting up an integration tests. These helpers can be found at <https://github.com/cosmos/cosmos-sdk/blob/main/testutil/integration>.
### Example
```go reference
https://github.com/cosmos/cosmos-sdk/blob/a2f73a7dd37bea0ab303792c55fa1e4e1db3b898/testutil/integration/example_test.go#L30-L116
```
## Deterministic and Regression tests
Tests are written for queries in the Cosmos SDK which have `module_query_safe` Protobuf annotation.
Each query is tested using 2 methods:
* Use property-based testing with the [`rapid`](https://pkg.go.dev/pgregory.net/rapid@v0.5.3) library. The property that is tested is that the query response and gas consumption are the same upon 1000 query calls.
* Regression tests are written with hardcoded responses and gas, and verify they don't change upon 1000 calls and between SDK patch versions.
Here's an example of regression tests:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/tests/integration/bank/keeper/deterministic_test.go#L134-L151
```
## Simulations
Simulations uses as well a minimal application, built with [`depinject`](../packages/01-depinject.md):
:::note
You can as well use the `AppConfig` `configurator` for creating an `AppConfig` [inline](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/slashing/app_test.go#L54-L62). There is no difference between those two ways, use whichever you prefer.
:::
Following is an example for `x/gov/` simulations:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/simulation/operations_test.go#L406-L430
```
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/gov/simulation/operations_test.go#L90-L132
```
## End-to-end Tests
End-to-end tests are at the top of the [test pyramid](https://martinfowler.com/articles/practical-test-pyramid.html).
They must test the whole application flow, from the user perspective (for instance, CLI tests). They are located under [`/tests/e2e`](https://github.com/cosmos/cosmos-sdk/tree/main/tests/e2e).
<!-- @julienrbrt: makes more sense to use an app wired app to have 0 simapp dependencies -->
For that, the SDK is using `simapp` but you should use your own application (`appd`).
Here are some examples:
* SDK E2E tests: <https://github.com/cosmos/cosmos-sdk/tree/main/tests/e2e>.
* Cosmos Hub E2E tests: <https://github.com/cosmos/gaia/tree/main/tests/e2e>.
* Osmosis E2E tests: <https://github.com/osmosis-labs/osmosis/tree/main/tests/e2e>.
:::note warning
The SDK is in the process of creating its E2E tests, as defined in [ADR-59](https://docs.cosmos.network/main/architecture/adr-059-test-scopes.html). This page will eventually be updated with better examples.
:::
## Learn More
Learn more about testing scope in [ADR-59](https://docs.cosmos.network/main/architecture/adr-059-test-scopes.html).
+31
View File
@@ -0,0 +1,31 @@
---
sidebar_position: 1
---
# PreBlocker
:::note Synopsis
`PreBlocker` is optional method module developers can implement in their module. They will be triggered before [`BeginBlock`](../../develop/advanced/00-baseapp.md#beginblock).
:::
:::note Pre-requisite Readings
* [Module Manager](./01-module-manager.md)
:::
## PreBlocker
There are two semantics around the new lifecycle method:
- It runs before the `BeginBlocker` of all modules
- It can modify consensus parameters in storage, and signal the caller through the return value.
When it returns `ConsensusParamsChanged=true`, the caller must refresh the consensus parameter in the deliver context:
```
app.finalizeBlockState.ctx = app.finalizeBlockState.ctx.WithConsensusParams(app.GetConsensusParams())
```
The new ctx must be passed to all the other lifecycle methods.
<!-- TODO: leaving this here to update docs with core api changes -->
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Building Modules",
"position": 1,
"link": null
}
+15
View File
@@ -0,0 +1,15 @@
---
sidebar_position: 1
---
# SDK Migrations
To smoothen the update to the latest stable release, the SDK includes a CLI command for hard-fork migrations (under the `<appd> genesis migrate` subcommand).
Additionally, the SDK includes in-place migrations for its core modules. These in-place migrations are useful to migrate between major releases.
* Hard-fork migrations are supported from the last major release to the current one.
* [In-place module migrations](https://docs.cosmos.network/main/core/upgrade#overwriting-genesis-functions) are supported from the last two major releases to the current one.
Migration from a version older than the last two major releases is not supported.
When migrating from a previous version, refer to the [`UPGRADING.md`](./02-upgrading.md) and the `CHANGELOG.md` of the version you are migrating to.
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Migrations",
"position": 3,
"link": null
}
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Modules",
"position": 2,
"link": null
}
+39
View File
@@ -0,0 +1,39 @@
---
sidebar_position: 0
---
# Packages
The Cosmos SDK is a collection of Go modules. This section provides documentation on various packages that can used when developing a Cosmos SDK chain.
It lists all standalone Go modules that are part of the Cosmos SDK.
:::tip
For more information on SDK modules, see the [SDK Modules](https://docs.cosmos.network/main/modules) section.
For more information on SDK tooling, see the [Tooling](https://docs.cosmos.network/main/tooling) section.
:::
## Core
* [Core](https://pkg.go.dev/cosmossdk.io/core) - Core library defining SDK interfaces ([ADR-063](https://docs.cosmos.network/main/architecture/adr-063-core-module-api))
* [API](https://pkg.go.dev/cosmossdk.io/api) - API library containing generated SDK Pulsar API
* [Store](https://pkg.go.dev/cosmossdk.io/store) - Implementation of the Cosmos SDK store
## State Management
* [Collections](./02-collections.md) - State management library
* [ORM](./03-orm.md) - State management library
## Automation
* [Depinject](./01-depinject.md) - Dependency injection framework
* [Client/v2](https://pkg.go.dev/cosmossdk.io/client/v2) - Library powering [AutoCLI](https://docs.cosmos.network/main/core/autocli)
## Utilities
* [Log](https://pkg.go.dev/cosmossdk.io/log) - Logging library
* [Errors](https://pkg.go.dev/cosmossdk.io/errors) - Error handling library
* [Math](https://pkg.go.dev/cosmossdk.io/math) - Math library for SDK arithmetic operations
## Example
* [SimApp](https://pkg.go.dev/cosmossdk.io/simapp) - SimApp is **the** sample Cosmos SDK chain. This package should not be imported in your application.
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Packages",
"position": 4,
"link": null
}
+113
View File
@@ -0,0 +1,113 @@
---
sidebar_position: 1
---
# Protocol Buffers
It is known that Cosmos SDK uses protocol buffers extensively, this document is meant to provide a guide on how it is used in the cosmos-sdk.
To generate the proto file, the Cosmos SDK uses a docker image, this image is provided to all to use as well. The latest version is `ghcr.io/cosmos/proto-builder:0.12.x`
Below is the example of the Cosmos SDK's commands for generating, linting, and formatting protobuf files that can be reused in any applications makefile.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/Makefile#L411-L432
```
The script used to generate the protobuf files can be found in the `scripts/` directory.
```shell reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/scripts/protocgen.sh
```
## Buf
[Buf](https://buf.build) is a protobuf tool that abstracts the needs to use the complicated `protoc` toolchain on top of various other things that ensure you are using protobuf in accordance with the majority of the ecosystem. Within the cosmos-sdk repository there are a few files that have a buf prefix. Lets start with the top level and then dive into the various directories.
### Workspace
At the root level directory a workspace is defined using [buf workspaces](https://docs.buf.build/configuration/v1/buf-work-yaml). This helps if there are one or more protobuf containing directories in your project.
Cosmos SDK example:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/buf.work.yaml#L6-L9
```
### Proto Directory
Next is the `proto/` directory where all of our protobuf files live. In here there are many different buf files defined each serving a different purpose.
```bash
├── README.md
├── buf.gen.gogo.yaml
├── buf.gen.pulsar.yaml
├── buf.gen.swagger.yaml
├── buf.lock
├── buf.md
├── buf.yaml
├── cosmos
└── tendermint
```
The above diagram all the files and directories within the Cosmos SDK `proto/` directory.
#### `buf.gen.gogo.yaml`
`buf.gen.gogo.yaml` defines how the protobuf files should be generated for use with in the module. This file uses [gogoproto](https://github.com/gogo/protobuf), a separate generator from the google go-proto generator that makes working with various objects more ergonomic, and it has more performant encode and decode steps
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.gogo.yaml#L1-L9
```
:::tip
Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code)
:::
#### `buf.gen.pulsar.yaml`
`buf.gen.pulsar.yaml` defines how protobuf files should be generated using the [new golang apiv2 of protobuf](https://go.dev/blog/protobuf-apiv2). This generator is used instead of the google go-proto generator because it has some extra helpers for Cosmos SDK applications and will have more performant encode and decode than the google go-proto generator. You can follow the development of this generator [here](https://github.com/cosmos/cosmos-proto).
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.pulsar.yaml#L1-L18
```
:::tip
Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code)
:::
#### `buf.gen.swagger.yaml`
`buf.gen.swagger.yaml` generates the swagger documentation for the query and messages of the chain. This will only define the REST API end points that were defined in the query and msg servers. You can find examples of this [here](https://github.com/cosmos/cosmos-sdk/blob/main/proto/cosmos/bank/v1beta1/query.proto#L19)
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.gen.swagger.yaml#L1-L6
```
:::tip
Example of how to define `gen` files can be found [here](https://docs.buf.build/tour/generate-go-code)
:::
#### `buf.lock`
This is a autogenerated file based off the dependencies required by the `.gen` files. There is no need to copy the current one. If you depend on cosmos-sdk proto definitions a new entry for the Cosmos SDK will need to be provided. The dependency you will need to use is `buf.build/cosmos/cosmos-sdk`.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.lock#L1-L16
```
#### `buf.yaml`
`buf.yaml` defines the [name of your package](https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.yaml#L3), which [breakage checker](https://docs.buf.build/tour/detect-breaking-changes) to use and how to [lint your protobuf files](https://docs.buf.build/tour/lint-your-api).
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/proto/buf.yaml#L1-L24
```
We use a variety of linters for the Cosmos SDK protobuf files. The repo also checks this in ci.
A reference to the github actions can be found [here](https://github.com/cosmos/cosmos-sdk/blob/main/.github/workflows/proto.yml#L1-L32)
```go reference
https://github.com/cosmos/cosmos-sdk/blob/main/.github/workflows/proto.yml#L1-L32
```
+19
View File
@@ -0,0 +1,19 @@
---
sidebar_position: 0
---
# Tools
This section provides documentation on various tooling maintained by the SDK team.
This includes tools for development, operating a node, and ease of use of a Cosmos SDK chain.
## CLI Tools
* [Cosmovisor](./01-cosmovisor.md)
* [Confix](./02-confix.md)
* [Hubl](./03-hubl.md)
* [Rosetta](https://docs.cosmos.network/main/run-node/rosetta)
## Other Tools
* [Protocol Buffers](./00-protobuf.md)
+5
View File
@@ -0,0 +1,5 @@
{
"label": "Tooling",
"position": 5,
"link": null
}