Skip to main content
Version: v30

Upgrading a Blockchain to use IGNITE® CLI v0.18

IGNITE® CLI v0.18 comes with Cosmos SDK v0.44. This version of Cosmos SDK introduced changes that are not compatible with chains that were scaffolded with IGNITE® CLI versions lower than v0.18.

Important: After upgrading from IGNITE® CLI v0.17.3 to IGNITE® CLI v0.18, you must update the default blockchain template to use blockchains that were scaffolded with earlier versions.

These instructions are written for a blockchain that was scaffolded with the following command:

ignite scaffold chain github.com/username/mars

If you used a different module path, replace username and mars with the correct values for your blockchain.

Blockchain​

For each file listed, make the required changes to the source code of the blockchain template.

go.mod​

module github.com/username/mars

go 1.16

require (
github.com/cosmos/cosmos-sdk v0.44.0
github.com/cosmos/ibc-go v1.2.0
github.com/gogo/protobuf v1.3.3
github.com/google/go-cmp v0.5.6 // indirect
github.com/gorilla/mux v1.8.0
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/spf13/cast v1.3.1
github.com/spf13/cobra v1.1.3
github.com/stretchr/testify v1.7.0
github.com/tendermint/spm v0.1.6
github.com/tendermint/tendermint v0.34.13
github.com/tendermint/tm-db v0.6.4
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83
google.golang.org/grpc v1.40.0
)

replace (
github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
google.golang.org/grpc => google.golang.org/grpc v1.33.2
)

app/app.go​

package app

import (
//...
// Add the following packages:
"github.com/cosmos/cosmos-sdk/x/feegrant"
feegrantkeeper "github.com/cosmos/cosmos-sdk/x/feegrant/keeper"
feegrantmodule "github.com/cosmos/cosmos-sdk/x/feegrant/module"

"github.com/cosmos/ibc-go/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/modules/core"
ibcclient "github.com/cosmos/ibc-go/modules/core/02-client"
ibcporttypes "github.com/cosmos/ibc-go/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/modules/core/24-host"
ibckeeper "github.com/cosmos/ibc-go/modules/core/keeper"
// Remove the following packages:
// transfer "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer"
// ibctransferkeeper "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/keeper"
// ibctransfertypes "github.com/cosmos/cosmos-sdk/x/ibc/applications/transfer/types"
// ibc "github.com/cosmos/cosmos-sdk/x/ibc/core"
// ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client"
// porttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/05-port/types"
// ibchost "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
// ibckeeper "github.com/cosmos/cosmos-sdk/x/ibc/core/keeper"
)

var (
//...
ModuleBasics = module.NewBasicManager(
//...
slashing.AppModuleBasic{},
// Add feegrantmodule.AppModuleBasic{},
feegrantmodule.AppModuleBasic{}, // <--
ibc.AppModuleBasic{},
//...
)
//...
)

type App struct {
//...
// Replace codec.Marshaler with codec.Codec
appCodec codec.Codec // <--
// Add FeeGrantKeeper
FeeGrantKeeper feegrantkeeper.Keeper // <--
}

func New( /*...*/ ) {
//bApp.SetAppVersion(version.Version)
bApp.SetVersion(version.Version) // <--

keys := sdk.NewKVStoreKeys(
//...
upgradetypes.StoreKey,
// Add feegrant.StoreKey
feegrant.StoreKey, // <--
evidencetypes.StoreKey,
//...
)

app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper) // <--
// Add app.BaseApp as the last argument to upgradekeeper.NewKeeper
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp)

app.IBCKeeper = ibckeeper.NewKeeper(
// Add app.UpgradeKeeper
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
)

govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
//...
// Replace NewClientUpdateProposalHandler with NewClientProposalHandler
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))

// Replace porttypes with ibcporttypes
ibcRouter := ibcporttypes.NewRouter()

app.mm.SetOrderBeginBlockers(
upgradetypes.ModuleName,
// Add capabilitytypes.ModuleName,
capabilitytypes.ModuleName,
minttypes.ModuleName,
//...
// Add feegrant.ModuleName,
feegrant.ModuleName,
)

// Add app.appCodec as an argument to module.NewConfigurator:
app.mm.RegisterServices(module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter()))

// Replace:
// app.SetAnteHandler(
// ante.NewAnteHandler(
// app.AccountKeeper, app.BankKeeper, ante.DefaultSigVerificationGasConsumer,
// encodingConfig.TxConfig.SignModeHandler(),
// ),
// )

// With the following:
anteHandler, err := ante.NewAnteHandler(
ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
FeegrantKeeper: app.FeeGrantKeeper,
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
)
if err != nil {
panic(err)
}
app.SetAnteHandler(anteHandler)

// Remove the following:
// ctx := app.BaseApp.NewUncachedContext(true, tmproto.Header{})
// app.CapabilityKeeper.InitializeAndSeal(ctx)
}

func (app *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState GenesisState
if err := tmjson.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
// Add the following:
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
}

// Replace Marshaler with Codec
func (app *App) AppCodec() codec.Codec {
return app.appCodec
}

// Replace BinaryMarshaler with BinaryCodec
func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper {
//...
}

app/genesis.go​

// Replace codec.JSONMarshaler with codec.JSONCodec
func NewDefaultGenesisState(cdc codec.JSONCodec) GenesisState {
// ...
}

testutil/keeper/mars.go​

Add the following code:

package keeper

import (
"testing"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
"github.com/username/mars/x/mars/keeper"
"github.com/username/mars/x/mars/types"
)

func MarsKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
storeKey := sdk.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)

db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil)
require.NoError(t, stateStore.LoadLatestVersion())

registry := codectypes.NewInterfaceRegistry()
k := keeper.NewKeeper(
codec.NewProtoCodec(registry),
storeKey,
memStoreKey,
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
return k, ctx
}

If mars is an IBC-enabled module, add the following code, instead:

package keeper

import (
"testing"

"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/store"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
typesparams "github.com/cosmos/cosmos-sdk/x/params/types"
ibckeeper "github.com/cosmos/ibc-go/modules/core/keeper"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"
"github.com/username/test/x/mars/keeper"
"github.com/username/test/x/mars/types"
)

func MarsKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
logger := log.NewNopLogger()

storeKey := sdk.NewKVStoreKey(types.StoreKey)
memStoreKey := storetypes.NewMemoryStoreKey(types.MemStoreKey)

db := tmdb.NewMemDB()
stateStore := store.NewCommitMultiStore(db)
stateStore.MountStoreWithDB(storeKey, sdk.StoreTypeIAVL, db)
stateStore.MountStoreWithDB(memStoreKey, sdk.StoreTypeMemory, nil)
require.NoError(t, stateStore.LoadLatestVersion())

registry := codectypes.NewInterfaceRegistry()
appCodec := codec.NewProtoCodec(registry)
capabilityKeeper := capabilitykeeper.NewKeeper(appCodec, storeKey, memStoreKey)

amino := codec.NewLegacyAmino()
ss := typesparams.NewSubspace(appCodec,
amino,
storeKey,
memStoreKey,
"MarsSubSpace",
)
IBCKeeper := ibckeeper.NewKeeper(
appCodec,
storeKey,
ss,
nil,
nil,
capabilityKeeper.ScopeToModule("MarsIBCKeeper"),
)

k := keeper.NewKeeper(
codec.NewProtoCodec(registry),
storeKey,
memStoreKey,
IBCKeeper.ChannelKeeper,
&IBCKeeper.PortKeeper,
capabilityKeeper.ScopeToModule("MarsScopedKeeper"),
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, logger)
return k, ctx
}

testutil/network/network.go​

func DefaultConfig() network.Config {
// ...
return network.Config{
// ...
// Add sdk.DefaultPowerReduction
AccountTokens: sdk.TokensFromConsensusPower(1000, sdk.DefaultPowerReduction),
StakingTokens: sdk.TokensFromConsensusPower(500, sdk.DefaultPowerReduction),
BondedTokens: sdk.TokensFromConsensusPower(100, sdk.DefaultPowerReduction),
// ...
}
}

testutil/sample/sample.go​

Add the following code:

package sample

import (
"github.com/cosmos/cosmos-sdk/crypto/keys/ed25519"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// AccAddress returns a sample account address
func AccAddress() string {
pk := ed25519.GenPrivKey().PubKey()
addr := pk.Address()
return sdk.AccAddress(addr).String()
}

BandChain Support​

If your module includes integration with BandChain, added manually or scaffolded with ignite scaffold band, upgrade the github.com/bandprotocol/bandchain-packet package to v0.0.2 in go.mod.

Module​

x/mars/keeper/keeper.go​

package keeper

// ...

type (
Keeper struct {
// Replace Marshaler with BinaryCodec
cdc codec.BinaryCodec
//...
}
)

func NewKeeper(
// Replace Marshaler with BinaryCodec
cdc codec.BinaryCodec,
// ...
) *Keeper {
// ...
}

x/mars/keeper/msg_server_test.go​

package keeper_test

import (
//...
// Add the following:
keepertest "github.com/username/mars/testutil/keeper"
"github.com/username/mars/x/mars/keeper"
)

func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) {
// Replace
// keeper, ctx := setupKeeper(t)
// return NewMsgServerImpl(*keeper), sdk.WrapSDKContext(ctx)

// With the following:
k, ctx := keepertest.MarsKeeper(t)
return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx)
}

x/mars/module.go​

package mars

type AppModuleBasic struct {
// Replace Marshaler with BinaryCodec
cdc codec.BinaryCodec
}

// Replace Marshaler with BinaryCodec
func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic {
return AppModuleBasic{cdc: cdc}
}

// Replace JSONMarshaler with JSONCodec
func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage {
return cdc.MustMarshalJSON(types.DefaultGenesis())
}

// Replace JSONMarshaler with JSONCodec
func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error {
//...
}

// Replace codec.Marshaller with codec.Codec
func NewAppModule(cdc codec.Codec, keeper keeper.Keeper) AppModule {
//...
}

// Replace JSONMarshaler with JSONCodec
func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate {
//...
}

// Replace JSONMarshaler with JSONCodec
func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage {
//...
}

// Add the following
func (AppModule) ConsensusVersion() uint64 { return 2 }