[docs]: Stargate migration guides (#7771)

* init

* Add page contents

* Update migrate a module to stargate

* Update links

* Add querier

* add baseapp migration guide

* Add upgrade instructions

* Add TODO for missing udpates

* Add dependencies

* address review comments

* remove unused

* gaiad => simd

* Add ibc state jq cmd

* Update docs/migrations/README.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/README.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/README.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/README.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Created a modules.md file

* Update chain migration guide

* Rename to App migration

* Add new paragraph

* Add some initial sections

* Add msg and queries

* Finish modules

* Add client

* Add update guide

* Rename title

* More tweaks

* Update chain upgrade one

* Remove useless change

* Don't repeat

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>

* Small update

* Use rc6

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/chain-upgrade-guide-040.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* Update docs/migrations/app_and_modules.md

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* reviews

* Review

Co-authored-by: Amaury <amaury.martiny@protonmail.com>
Co-authored-by: Marie Gauthier <marie.gauthier63@gmail.com>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
This commit is contained in:
Anil Kumar Kammari 2021-01-06 17:13:52 +05:30 committed by GitHub
parent 031eec3e9d
commit 8ba297f25a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 427 additions and 24 deletions

View File

@ -58,11 +58,11 @@ The Cosmos SDK comes with a large set of stores to persist the state of applicat
At its very core, a Cosmos SDK `store` is an object that holds a `CacheWrapper` and has a `GetStoreType()` method:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L15-L18
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L15-L18
The `GetStoreType` is a simple method that returns the type of store, whereas a `CacheWrapper` is a simple interface that implements store read caching and write branching through `Write` method:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L240-L264
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L240-L264
Branching and cache is used ubiquitously in the Cosmos SDK and required to be implemented on every store type. A storage branch creates an isolated, ephemeral branch of a store that can be passed around and updated without affecting the main underlying store. This is used to trigger temporary state-transitions that may be reverted later should an error occur. Read more about it in [context](./context.md#Store-branching)
@ -70,11 +70,11 @@ Branching and cache is used ubiquitously in the Cosmos SDK and required to be im
A commit store is a store that has the ability to commit changes made to the underlying tree or db. The Cosmos SDK differentiates simple stores from commit stores by extending the basic store interfaces with a `Committer`:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L29-L33
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L29-L33
The `Committer` is an interface that defines methods to persist changes to disk:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L20-L27
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L20-L27
The `CommitID` is a deterministic commit of the state tree. Its hash is returned to the underlying consensus engine and stored in the block header. Note that commit store interfaces exist for various purposes, one of which is to make sure not every object can commit the store. As part of the [object-capabilities model](./ocap.md) of the Cosmos SDK, only `baseapp` should have the ability to commit stores. For example, this is the reason why the `ctx.KVStore()` method by which modules typically access stores returns a `KVStore` and not a `CommitKVStore`.
@ -86,7 +86,7 @@ The Cosmos SDK comes with many types of stores, the most used being [`CommitMult
Each Cosmos SDK application holds a multistore at its root to persist its state. The multistore is a store of `KVStores` that follows the `Multistore` interface:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L104-L133
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L104-L133
If tracing is enabled, then branching the multistore will firstly wrap all the underlying `KVStore` in [`TraceKv.Store`](#tracekv-store).
@ -94,11 +94,11 @@ If tracing is enabled, then branching the multistore will firstly wrap all the u
The main type of `Multistore` used in the Cosmos SDK is `CommitMultiStore`, which is an extension of the `Multistore` interface:
+++https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L141-L184
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L141-L184
As for concrete implementation, the [`rootMulti.Store`] is the go-to implementation of the `CommitMultiStore` interface.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/rootmulti/store.go#L43-L61
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/rootmulti/store.go#L43-L61
The `rootMulti.Store` is a base-layer multistore built around a `db` on top of which multiple `KVStores` can be mounted, and is the default multistore store used in [`baseapp`](./baseapp.md).
@ -106,7 +106,7 @@ The `rootMulti.Store` is a base-layer multistore built around a `db` on top of w
Whenever the `rootMulti.Store` needs to be branched, a [`cachemulti.Store`](https://github.com/cosmos/cosmos-sdk/blob/master/store/cachemulti/store.go) is used.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachemulti/store.go#L17-L28
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/cachemulti/store.go#L17-L28
`cachemulti.Store` branches all substores (creates a virtual store for each substore) in its constructor and hold them in `Store.stores`. Moreover cachese all read queries. `Store.GetKVStore()` returns the store from `Store.stores`, and `Store.Write()` recursively calls `CacheWrap.Write()` on all the substores.
@ -120,17 +120,17 @@ Individual `KVStore`s are used by modules to manage a subset of the global state
`CommitKVStore`s are declared by proxy of their respective `key` and mounted on the application's [multistore](#multistore) in the [main application file](../basics/app-anatomy.md#core-application-file). In the same file, the `key` is also passed to the module's `keeper` that is responsible for managing the store.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/store.go#L189-L219
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/store.go#L189-L219
Apart from the traditional `Get` and `Set` methods, a `KVStore` must provide an `Iterator(start, end)` method which returns an `Iterator` object. It is used to iterate over a range of keys, typically keys that share a common prefix. Below is an example from the bank's module keeper, used to iterate over all account balances:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/bank/keeper/view.go#L115-L134
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/keeper/view.go#L115-L134
### `IAVL` Store
The default implementation of `KVStore` and `CommitKVStore` used in `baseapp` is the `iavl.Store`.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/iavl/store.go#L37-L40
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/iavl/store.go#L37-L40
`iavl` stores are based around an [IAVL Tree](https://github.com/tendermint/iavl), a self-balancing binary tree which guarantees that:
@ -144,7 +144,7 @@ The documentation on the IAVL Tree is located [here](https://github.com/cosmos/i
`dbadapter.Store` is a adapter for `dbm.DB` making it fulfilling the `KVStore` interface.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/dbadapter/store.go#L13-L16
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/dbadapter/store.go#L13-L16
`dbadapter.Store` embeds `dbm.DB`, meaning most of the `KVStore` interface functions are implemented. The other functions (mostly miscellaneous) are manually implemented. This store is primarily used within [Transient Stores](#transient-stores)
@ -152,17 +152,17 @@ The documentation on the IAVL Tree is located [here](https://github.com/cosmos/i
`Transient.Store` is a base-layer `KVStore` which is automatically discarded at the end of the block.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/transient/store.go#L13-L16
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/transient/store.go#L13-L16
`Transient.Store` is a `dbadapter.Store` with a `dbm.NewMemDB()`. All `KVStore` methods are reused. When `Store.Commit()` is called, a new `dbadapter.Store` is assigned, discarding previous reference and making it garbage collected.
This type of store is useful to persist information that is only relevant per-block. One example would be to store parameter changes (i.e. a bool set to `true` if a parameter changed in a block).
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/x/params/types/subspace.go#L20-L30
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/params/types/subspace.go#L20-L30
Transient stores are typically accessed via the [`context`](./context.md) via the `TransientStore()` method:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L232-L235
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/types/context.go#L232-L235
## KVStore Wrappers
@ -170,7 +170,7 @@ Transient stores are typically accessed via the [`context`](./context.md) via th
`cachekv.Store` is a wrapper `KVStore` which provides buffered writing / cached reading functionalities over the underlying `KVStore`.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/cachekv/store.go#L27-L34
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/cachekv/store.go#L27-L34
This is the type used whenever an IAVL Store needs to be branched to create an isolated store (typically when we need to mutate a state that might be reverted later).
@ -188,27 +188,27 @@ This is the type used whenever an IAVL Store needs to be branched to create an i
### `GasKv` Store
Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications.
Cosmos SDK applications use [`gas`](../basics/gas-fees.md) to track resources usage and prevent spam. [`GasKv.Store`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/gaskv/store.go) is a `KVStore` wrapper that enables automatic gas consumption each time a read or write to the store is made. It is the solution of choice to track storage usage in Cosmos SDK applications.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/gaskv/store.go#L13-L19
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/gaskv/store.go#L13-L19
When methods of the parent `KVStore` are called, `GasKv.Store` automatically consumes appropriate amount of gas depending on the `Store.gasConfig`:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L153-L162
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/gas.go#L153-L162
By default, all `KVStores` are wrapped in `GasKv.Stores` when retrieved. This is done in the `KVStore()` method of the [`context`](./context.md):
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/types/context.go#L227-L230
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/types/context.go#L227-L230
In this case, the default gas configuration is used:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/types/gas.go#L164-L175
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/types/gas.go#L164-L175
### `TraceKv` Store
`tracekv.Store` is a wrapper `KVStore` which provides operation tracing functionalities over the underlying `KVStore`. It is applied automatically by the Cosmos SDK on all `KVStore` if tracing is enabled on the parent `MultiStore`.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/tracekv/store.go#L20-L43
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/tracekv/store.go#L20-L43
When each `KVStore` methods are called, `tracekv.Store` automatically logs `traceOperation` to the `Store.writer`. `traceOperation.Metadata` is filled with `Store.context` when it is not nil. `TraceContext` is a `map[string]interface{}`.
@ -216,7 +216,7 @@ When each `KVStore` methods are called, `tracekv.Store` automatically logs `trac
`prefix.Store` is a wrapper `KVStore` which provides automatic key-prefixing functionalities over the underlying `KVStore`.
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc3/store/prefix/store.go#L15-L21
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/store/prefix/store.go#L15-L21
When `Store.{Get, Set}()` is called, the store forwards the call to its parent, with the key prefixed with the `Store.prefix`.

View File

@ -8,4 +8,6 @@ parent:
This folder contains all the migration guides to update your app and modules to Cosmos v0.40 Stargate.
1. [App and Modules Migration](./app_and_modules.md)
1. [Chain Upgrade Guide to v0.40](./chain-upgrade-guide-040.md)
1. [REST Endpoints Migration](./rest.md)

View File

@ -0,0 +1,239 @@
<!--
order: 1
-->
# App and Modules Migration
The following document describes the changes to update your app and modules from Cosmos SDK v0.39 to v0.40,
a.k.a. Stargate release. {synopsis}
## Update Tooling
Make sure to have the following dependencies before updating your app to v0.40:
- Go 1.15+
- Docker
- Node.js v12.0+ (optional, for generating Swagger docs)
In Cosmos-SDK we manage the project using Makefile. Your own app can use a similar Makefile to the [Cosmos SDK's one](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/Makefile). More specifically, below are some _make_ commands that might be useful for your own app, related to the introduction of Protocol Buffers:
- `proto-update-deps` - To download/update the required thirdparty `proto` definitions.
- `proto-gen` - To auto generate proto code.
- `proto-check-breaking` - To check proto breaking changes.
- `proto-format` - To format proto files.
## Updating Modules
This section outlines how to upgrade your module to v0.40. There is also a whole section about [building modules](../building-modules/README.md) from scratch, it might serve as a useful guide.
### Protocol Buffers
As outlined in our [encoding guide](../core/encoding.md), one of the most significant improvements introduced in Cosmos SDK v0.40 is Protobuf.
The rule of thumb is that any object that needs to be serialized (into binary or JSON) must implement `proto.Message` and must be serializable into Protobuf format. The easiest way to do it is to use Protobuf type definition and `protoc` compiler to generate the structures and functions for you. In practice, the three following categories of types must be converted to Protobuf messages:
- client-facing types: `Msg`s, query requests and responses. This is because client will send these types over the wire to your app.
- objects that are stored in state. This is because the SDK stores the binary representation of these types in state.
- genesis types. These are used when importing and exporting state snapshots during chain upgrades.
Let's have a look at [x/auth's](../../x/auth/spec/README.md) `BaseAccount` objects, which are stored in a state. The migration looks like:
```diff
// We were definining `MsgSend` as a Go struct in v0.39.
- // https://github.com/cosmos/cosmos-sdk/blob/v0.39.2/x/bank/internal/types/msgs.go#L12-L16
- type BaseAccount struct {
- Address sdk.AccAddress `json:"address" yaml:"address"`
- Coins sdk.Coins `json:"coins" yaml:"coins"`
- PubKey crypto.PubKey `json:"public_key" yaml:"public_key"`
- AccountNumber uint64 `json:"account_number" yaml:"account_number"`
- Sequence uint64 `json:"sequence" yaml:"sequence"`
- }
// And it should be converted to a Protobuf message in v0.40.
+ // https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/proto/cosmos/auth/v1beta1/auth.proto#L13-L25
+ message BaseAccount {
+ string address = 1;
+ google.protobuf.Any pub_key = 2
+ [(gogoproto.jsontag) = "public_key,omitempty", (gogoproto.moretags) = "yaml:\"public_key\""];
+ uint64 account_number = 3 [(gogoproto.moretags) = "yaml:\"account_number\""];
+ uint64 sequence = 4;
+ }
}
```
In general, we recommend to put all the Protobuf definitions in your module's subdirectory under a root `proto/` folder, as described in [ADR-023](../architecture/adr-023-protobuf-naming.md). This ADR also contains other useful information on naming conventions.
You might have noticed that the `PubKey` interface in v0.39's `BaseAccount` has been transformed into an `Any`. For storing interfaces, we use Protobuf's `Any` message, which is a struct that can hold arbitrary content. Please refer to the [encoding FAQ](../core/encoding.md#faq) to learn how to handle interfaces and `Any`s.
Once all your Protobuf messages are defined, use the `make proto-gen` command defined in the [tooling section](#tooling) to generate Go structs. These structs will be generated into `*.pb.go` files. As a quick example, here is the generated Go struct for the Protobuf BaseAccount we defined above:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/auth/types/auth.pb.go#L28-L36
There might be some back and forth removing old Go structs/interfaces and defining new Protobuf messages before your Go app compiles and your tests pass.
### Create `Msg` and `Query` Services
Cosmos SDK v0.40 uses Protobuf services to define state transitions (`Msg`s) and state queries, please read [the building modules guide on those services](../building-modules/messages-and-queries.md) for an overview.
#### `Msg` Service
For migrating `Msg`s, the handler pattern (inside the `handler.go` file) is deprecated. You may still keep it if you wish to support `Msg`s defined in older versions of the SDK. However, it is strongly recommended to add a `Msg` service to your Protobuf files, and each old `Msg` should be converted into a service method. Taking [x/bank's](../../x/bank/spec/README.md) `MsgSend` as an example, we have a corresponding `cosmos.bank.v1beta1.Msg/Send` service method:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/proto/cosmos/bank/v1beta1/tx.proto#L10-L31
A state transition is therefore modelized as a Protobuf service method, with a method request, and an (optionally empty) method response.
After defining your `Msg` service, run the `make proto-gen` script again to generate `Msg` server interfaces. The name of this interface is simply `MsgServer`. The implementation of this interface should follow exactly the implementation of the old `Msg` handlers, which, in most cases, defers the actual state transition logic to the [keeper](../building-modules/keeper.md). You may implement a `MsgServer` directly on the keeper, or you can do it using a new struct (e.g. called `msgServer`) that references the module's keeper.
For more information, please check our [`Msg` service guide](../building-modules/msg-services.md).
#### `Query` Service
For migrating state queries, the querier pattern (inside the `querier.go` file) is deprecated. You may still keep this file to support legacy queries, but it is strongly recommended to use a Protobuf `Query` service to handle state queries.
Each query endpoint is now defined as a separate service method in the `Query` service. Still taking `x/bank` as an example, here are the queries to fetch an account's balances:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/proto/cosmos/bank/v1beta1/query.proto#L12-L23
Each query has its own `Request` and `Response` types. Please also note the `google.api.http` option (coming from [`grpc-gateway`](https://github.com/grpc-ecosystem/grpc-gateway)) on each service method. `grpc-gateway` is a tool that exposes `Query` service methods as REST endpoints. Adding this annotation will expose these endpoints not only as gRPC endpoints, but also as REST endpoints. An overview of gRPC versus REST can be found [here](../core/grpc_rest.md).
After defining the `Query` Protobuf service, run the `make proto-gen` command to generate corresponding interfaces. The interface that needs to be implemented by your module is `QueryServer`. This interface can be implemented on the [keeper](../building-modules/keeper.md) directly, or on a struct (e.g. called `queryServer`) that references the module's keeper. The logic of the implementation, namely the logic that fetches data from the module's store and performs unmarshalling, can be deferred to the keeper.
Cosmos SDK v0.40 also comes with an efficient pagination, it now uses `Prefix` stores to make queries. There are 2 helpers for pagination, [`Paginate`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/types/query/pagination.go#L40-L42), [`FilteredPaginate`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/types/query/filtered_pagination.go#L9-L17).
For more information, please check our [`Query` service guide](../building-modules/query-services.md).
#### Wiring up `Msg` and `Query` Services
We added a new `RegisterServices` method that registers a module's `Msg` service and a `Query` service. It should be implemented by all modules, using a `Configurator` object:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/module.go#L99-L103
If you wish to expose your `Query` endpoints as REST endpoints (as proposed in the [`Query` Services paragraph](#query-services)), make sure to also implement the `RegisterGRPCGatewayRoutes` method:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/module.go#L69-L72
### Codec
If you still use Amino (which is deprecated since Stargate), you must register related types using the `RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)` method (previously it was called `RegisterCodec(cdc *codec.Codec)`).
Moreover, a new `RegisterInterfaces` method has been added to the `AppModule` interface that all modules must implement. This method must register the interfaces that Protobuf messages implement, as well as the service `Msg`s used in the module. An example from x/bank is given below:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/types/codec.go#L21-L34
### Keeper
The `Keeper` constructor now takes a `codec.Marshaler` instead of a concrete Amino codec. This `codec.Marshaler` is used to encode types as binary and save the bytes into the state. With an interface, you can define `codec.Marshaler` to be Amino or Protobuf on an app level, and keepers will use that encoding library to encode state. Please note that Amino is deprecated in v0.40, and we strongly recommend to use Protobuf. Internally, the SDK still uses Amino in a couple of places (legacy REST API, x/params, keyring...), but Amino is planned to be removed in a future release.
Keeping Amino for now can be useful if you wish to update to SDK v0.40 without doing a chain upgrade with a genesis migration. This will not require updating the stores, so you can migrate to Cosmos SDK v0.40 with less effort. However, as Amino will be removed in a future release, the chain migration with genesis export/import will need to be performed then.
Related to the keepers, each module's `AppModuleBasic` now also includes this `codec.Marshaler`:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/module.go#L35-L38
### CLI
Each modules may optionally expose CLI commands, and some changes are needed in these commands.
First, `context.CLIContext` is renamed to `client.Context` and moved to `github.com/cosmos/cosmos-sdk/client`.
Second, the global `viper` usage is removed from client and is replaced with Cobra' `cmd.Flags()`. There are two helpers to read common flags for CLI txs and queries:
```go
clientCtx, err := client.GetClientQueryContext(cmd)
clientCtx, err := client.GetClientTxContext(cmd)
```
Some other flags helper functions are transformed: `flags.PostCommands(cmds ...*cobra.Command) []*cobra.Command` and `flags.GetCommands(...)` usage is now replaced by `flags.AddTxFlagsToCmd(cmd *cobra.Command)` and `flags.AddQueryFlagsToCmd(cmd *cobra.Command)` respectively.
Moreover, new CLI commands don't take any codec as input anymore. Instead, the `clientCtx` can be retrieved from the `cmd` itself using the `GetClient{Query,Tx}Context` function above, and the codec as `clientCtx.JSONMarshaler`.
```diff
// v0.39
- func SendTxCmd(cdc *codec.Codec) *cobra.Command {
- cdc.MarshalJSON(...)
- }
// v0.40
+ func NewSendTxCmd() *cobra.Command {
+ clientCtx, err := client.GetClientTxContext(cmd)
+ clientCtx.JSONMarshaler.MarshalJSON(...)
+}
```
Finally, once your [`Query` services](#query-service) are wired up, the CLI commands should preferably use gRPC to communicate with the node. The gist is to create a `Query` or `Msg` client using the command's `clientCtx`, and perform the request using Protobuf's generated code. An example for querying x/bank balances is given here:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/x/bank/client/cli/query.go#L66-L94
### Miscelleanous
A number of other smaller breaking changes are also noteworthy.
| Before | After | Comment |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `alias.go` file | Removed | `alias` usage is removed, please see [#6311](https://github.com/cosmos/cosmos-sdk/issues/6311) for details. |
| `codec.New()` | `codec.NewLegacyAmino()` | Simple rename. |
| `DefaultGenesis()` | `DefaultGenesis(cdc codec.JSONMarshaler)` | `DefaultGenesis` takes a codec argument now |
| `ValidateGenesis()` | `ValidateGenesis(cdc codec.JSONMarshaler, config client.TxEncodingConfig, bz json.RawMessage)` | `ValidateGenesis` now requires `Marshaler`, `TxEncodingConfig`, `json.RawMessage` as input. |
| `Route() string` | `Route() sdk.Route` | For legacy handlers, return type of `Route()` method is changed from `string` to `"github.com/cosmos/cosmos-sdk/types".Route`. It should return a `NewRoute()` which includes `RouterKey` and `NewHandler` as params. |
| `QuerierHandler` | `LegacyQuerierHandler` | Simple rename. |
| `InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate` | InitGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate | `InitGenesis` now takes a codec input. |
| `ExportGenesis(ctx sdk.Context, data json.RawMessage) []abci.ValidatorUpdate` | ExportGenesis(ctx sdk.Context, cdc codec.JSONMarshaler, data json.RawMessage) []abci.ValidatorUpdate | `ExportGenesis` now takes a codec input. |
## Updating Your App
For a reference implementation used for demo purposes, you can refer to the SDK's [SimApp](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc6/simapp) for your app's migration. The most important changes are described in this section.
### Creating Codecs
With the introduction of Protobuf, each app needs to define the encoding library (Amino or Protobuf) to be used throughout the app. There is a central struct, [`EncodingConfig`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/simapp/params/encoding.go#L9-L11), which defines all information necessary for codecs. In your app, an example `EncodingConfig` with Protobuf as default codec might look like:
```go
// MakeEncodingConfig creates an EncodingConfig
func MakeEncodingConfig() params.EncodingConfig {
amino := codec.NewLegacyAmino()
interfaceRegistry := types.NewInterfaceRegistry()
marshaler := codec.NewProtoCodec(interfaceRegistry)
txCfg := tx.NewTxConfig(marshaler, tx.DefaultSignModes)
encodingConfig := params.EncodingConfig{
InterfaceRegistry: interfaceRegistry,
Marshaler: marshaler,
TxConfig: txCfg,
Amino: amino,
}
std.RegisterLegacyAminoCodec(encodingConfig.Amino)
std.RegisterInterfaces(encodingConfig.InterfaceRegistry)
ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino)
ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry)
return encodingConfig
}
```
These codecs are used to populate the following fields on your app (again, we are using SimApp for demo purposes):
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/simapp/app.go#L146-L153
As explained in the [modules migration section](#updating-modules), some functions and structs in modules require an additional `codec.Marshaler` argument. You should pass `app.appCodec` in these cases, and this will be the default codec used throughout the app.
### Registering Non-Module Protobuf Services
We described in the [modules migration section](#updating-modules) `Query` and `Msg` services defined in each module. The SDK also exposes two more module-agnostic services:
- the [Tx Service](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/proto/cosmos/tx/v1beta1/service.proto), to perform operations on transactions,
- the [Tendermint service](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/proto/cosmos/base/tendermint/v1beta1/query.proto), to have a more idiomatic interface to the [Tendermint RPC](https://docs.tendermint.com/master/rpc/).
These services are optional, if you wish to use them, or if you wish to add more module-agnostic Protobuf services into your app, then you need to add them inside `app.go`:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/simapp/app.go#L577-L585
### Registering `grpc-gateway` Routes
The exising `RegisterAPIRoutes` method on the `app` only registers [Legacy API routes](../core/grpc_rest.md#legacy-rest-api-routes). If you are using `grpc-gateway` REST endpoints as described [above](#query-service), then these endpoints need to be wired up to a HTTP server:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/simapp/app.go#L555-L575
## Next {hide}
Learn how to perform a [chain upgrade](./chain-upgrade-guide-040.md) to 0.40.

View File

@ -0,0 +1,162 @@
<!--
order: 2
-->
# Chain Upgrade Guide to v0.40
This document explains how to perform a chain upgrade from v0.39 to v0.40. {synopsis}
## Risks
As a validator, performing the upgrade procedure on your consensus nodes carries a heightened risk of double-signing and
being slashed: if your validator node votes for a block, and, in the same block time, restarts the upgraded node, this may lead to double-voting on a block.
The riskiest thing a validator can do is to discover that they made a mistake and repeat the upgrade procedure again during
the network startup. If you discover a mistake in the process, the best thing to do is wait for the network to start
before correcting it. If the network is halted and you have started with a different genesis file than the expected one,
seek advice from the validator community.
## Recovery
- Prior to exporting the state, the validators are encouraged to take a full data snapshot at exported height. Exported
height will be determined by a governance proposal. Data backup is usually done by copying daemon home directory,
e.g.: `~/.simd`
**Note:** we use "simd" as our app throughout this doc, be sure to replace with the name of your own binary.
It is critically important to back-up the validator state file, e.g.: `~/.simd/data/priv_validator_state.json` file
after stopping your daemon process. This file is updated every block as your validator participates in a consensus
rounds. It is a critical file needed to prevent double-signing, in case the upgrade fails, and the previous chain needs
to be restarted.
In the event that the upgrade does not succeed, validators and operators must downgrade back to old version of the
software and restore to their latest snapshot before restarting their nodes.
## Upgrade procedure
1. The procedure is to export the state from the old binary, and import it with the new binary. First, verify your old binary version (which should use `github.com/cosmos/cosmos-sdk@0.39.*`) before exporting the state.
```shell
simd version --long
```
1. Export the state from existing chain using the old binary.
```shell
simd export --for-zero-height --height <height> > v039_exported_state.json
```
1. Verify the SHA256 of the (sorted) exported genesis file:
```shell
$ jq -S -c -M '' v039_exported_state.json | shasum -a 256
[SHASUM_PLACEHOLDER] v039_exported_state.json
```
1. Cross check the hash with other peers (other validators) in the chat rooms.
1. Install the latest binary (which uses `github.com/cosmos/cosmos-sdk@0.40.*`).
1. Migrate the exported state to `github.com/cosmos/cosmos-sdk@0.40.*` compatible genesis state.
```shell
simd migrate v0.40 v039_exported_state.json --chain-id <new_chain_id> --genesis-time <new_genesis_time_in_utc> > new_v040_genesis.json
```
**Note:** The migrate command takes an input genesis state and migrates it to a targeted version. New `genesis-time` will be as mentioned in the governance proposal.
1. All the necessary state changes are handled in the `simd migrate v0.40` migration command. However, Tendermint parameters are **not** handled in this command. You might need to update these parameters manually.
In the recent versions of Tendermint, the following changes have been made:
- `consensus_params.evidence.max_num` has been renamed to `consensus_params.evidence.max_bytes`.
- `consensus_params.evidence.max_age` has been removed, and replaced by `consensus_params.evidence.max_age_duration` and `consensus_params.evidence.max_age_num_blocks`.
Make sure that your genesis JSON files contains the correct values specific to your chain. If the `simd migrate` errors with a message saying that the genesis file cannot be parsed, these are the fields to check first.
1. Verify the SHA256 of the migrated genesis file with other validators to make sure there are no manual errors in the process.
```shell
$ jq -S -c -M '' new_v040_genesis.json | shasum -a 256
[SHASUM_PLACEHOLDER] new_v040_genesis.json
```
1. Make sure to update the genesis parameters in the new genesis if any. All these details will be generally present in
the governance proposal.
1) If your chain is using IBC, make sure to add IBC initial genesis state to the genesis file. You can use the following command to add IBC initial genesis state to the genesis file.
```shell
cat new_040_genesis.json | jq '.app_state |= . + {"ibc":{"client_genesis":{"clients":[],"clients_consensus":[],"create_localhost":false},"connection_genesis":{"connections":[],"client_connection_paths":[]},"channel_genesis":{"channels":[],"acknowledgements":[],"commitments":[],"receipts":[],"send_sequences":[],"recv_sequences":[],"ack_sequences":[]}},"transfer":{"port_id":"transfer","denom_traces":[],"params":{"send_enabled":false,"receive_enabled":false}},"capability":{"index":"1","owners":[]}}' > new_040_genesis.json
```
**Note:** This would add IBC state with IBC's `send_enabled: false` and `receive_enabled: false`. Make sure to update them to `true` in the above command if are planning to enable IBC transactions with chain upgrade. Otherwise you can do it via a governance proposal.
1) Reset the old state.
**Note:** Be sure you have a complete backed up state of your node before proceeding with this step.
See Recovery for details on how to proceed.
```shell
simd unsafe-reset-all
```
1) Move the new genesis.json to your daemon config directory. Ex
```shell
cp new_v040_genesis.json ~/.simd/config/genesis.json
```
1) Update `~/.simd/config/app.toml` to include latest app configurations. [Here is the link](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc6/server/config/toml.go#L11-L164) to the default template for v0.40's `app.toml`. Make sure to
update your custom configurations as per your validator design, e.g. `gas_price`.
Compared to v0.39, some notable updates to `app.toml` are:
- API server is now configured to run in-process with daemon, previously it was a separate process, invoked by running rest-server
command i.e., `gaiacli rest-server`. Now it is in-process with daemon and can be enabled/disabled by API configuration:
```yaml
[api]
# Enable defines if the API server should be enabled.
enable = false
# Swagger defines if swagger documentation should automatically be registered.
swagger = false
```
`swagger` setting refers to enabling/disabling swagger docs API, i.e, `/swagger/` API endpoint.
- gRPC Configuration
```yaml
[grpc]
# Enable defines if the gRPC server should be enabled.
enable = true
# Address defines the gRPC server address to bind to.
address = "0.0.0.0:9090"
```
- State Sync Configuration
```yaml
# State sync snapshots allow other nodes to rapidly join the network without replaying historical
# blocks, instead downloading and applying a snapshot of the application state at a given height.
[state-sync]
# snapshot-interval specifies the block interval at which local state sync snapshots are
# taken (0 to disable). Must be a multiple of pruning-keep-every.
snapshot-interval = 0
# snapshot-keep-recent specifies the number of recent snapshots to keep and serve (0 to keep all).
snapshot-keep-recent = 2
```
1) Kill if any external `rest-server` process is running.
1) All set now! You can (re)start your daemon to validate on the upgraded network. Make sure to check your binary version
before starting the daemon:
```
simd version --long
```
## Next {hide}
Once your chain is upgraded, make sure to [update your clients' REST endpoints](./rest.md).

View File

@ -1,5 +1,5 @@
<!--
order: 1
order: 3
-->
# REST Endpoints Migration