wormhole/wormchain/app/app.go

995 lines
37 KiB
Go

package app
import (
"io"
"net/http"
"os"
"path/filepath"
"time"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
"github.com/cosmos/cosmos-sdk/client/rpc"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
store "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
authrest "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authtx "github.com/cosmos/cosmos-sdk/x/auth/tx"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/capability"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
"github.com/cosmos/cosmos-sdk/x/crisis"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrclient "github.com/cosmos/cosmos-sdk/x/distribution/client"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
"github.com/cosmos/cosmos-sdk/x/evidence"
evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
"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/cosmos-sdk/x/genutil"
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
"github.com/cosmos/cosmos-sdk/x/gov"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/cosmos/cosmos-sdk/x/mint"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/cosmos/cosmos-sdk/x/params"
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/cosmos/cosmos-sdk/x/upgrade"
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
transfer "github.com/cosmos/ibc-go/v4/modules/apps/transfer"
ibctransferkeeper "github.com/cosmos/ibc-go/v4/modules/apps/transfer/keeper"
ibctransfertypes "github.com/cosmos/ibc-go/v4/modules/apps/transfer/types"
ibc "github.com/cosmos/ibc-go/v4/modules/core"
ibcclient "github.com/cosmos/ibc-go/v4/modules/core/02-client"
ibcporttypes "github.com/cosmos/ibc-go/v4/modules/core/05-port/types"
ibchost "github.com/cosmos/ibc-go/v4/modules/core/24-host"
ibcante "github.com/cosmos/ibc-go/v4/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v4/modules/core/keeper"
"github.com/prometheus/client_golang/prometheus"
"github.com/spf13/cast"
abci "github.com/tendermint/tendermint/abci/types"
tmjson "github.com/tendermint/tendermint/libs/json"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"
"github.com/CosmWasm/wasmd/x/wasm"
wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
"github.com/tendermint/spm/cosmoscmd"
"github.com/tendermint/spm/openapiconsole"
"github.com/wormhole-foundation/wormchain/docs"
wormholemodule "github.com/wormhole-foundation/wormchain/x/wormhole"
wormholemoduleante "github.com/wormhole-foundation/wormchain/x/wormhole/ante"
wormholeclient "github.com/wormhole-foundation/wormchain/x/wormhole/client"
wormholemodulekeeper "github.com/wormhole-foundation/wormchain/x/wormhole/keeper"
wormholemoduletypes "github.com/wormhole-foundation/wormchain/x/wormhole/types"
// this line is used by starport scaffolding # stargate/app/moduleImport
"github.com/wormhole-foundation/wormchain/x/tokenfactory"
"github.com/wormhole-foundation/wormchain/x/tokenfactory/bindings"
tokenfactorykeeper "github.com/wormhole-foundation/wormchain/x/tokenfactory/keeper"
tokenfactorytypes "github.com/wormhole-foundation/wormchain/x/tokenfactory/types"
ibchooks "github.com/wormhole-foundation/wormchain/x/ibc-hooks"
ibchookskeeper "github.com/wormhole-foundation/wormchain/x/ibc-hooks/keeper"
ibchookstypes "github.com/wormhole-foundation/wormchain/x/ibc-hooks/types"
packetforward "github.com/strangelove-ventures/packet-forward-middleware/v4/router"
packetforwardkeeper "github.com/strangelove-ventures/packet-forward-middleware/v4/router/keeper"
packetforwardtypes "github.com/strangelove-ventures/packet-forward-middleware/v4/router/types"
ibccomposabilitymw "github.com/wormhole-foundation/wormchain/x/ibc-composability-mw"
ibccomposabilitymwkeeper "github.com/wormhole-foundation/wormchain/x/ibc-composability-mw/keeper"
ibccomposabilitytypes "github.com/wormhole-foundation/wormchain/x/ibc-composability-mw/types"
)
const (
AccountAddressPrefix = "wormhole"
Name = "wormchain"
)
// this line is used by starport scaffolding # stargate/wasm/app/enabledProposals
func getGovProposalHandlers() []govclient.ProposalHandler {
var govProposalHandlers []govclient.ProposalHandler
// this line is used by starport scaffolding # stargate/app/govProposalHandlers
govProposalHandlers = append(govProposalHandlers,
paramsclient.ProposalHandler,
distrclient.ProposalHandler,
upgradeclient.ProposalHandler,
upgradeclient.CancelProposalHandler,
wormholeclient.GuardianSetUpdateProposalHandler,
wormholeclient.WormholeGovernanceMessageProposalHandler,
// this line is used by starport scaffolding # stargate/app/govProposalHandler
)
return govProposalHandlers
}
// GetWasmOpts build wasm options
func GetWasmOpts(app *App, appOpts servertypes.AppOptions) []wasm.Option {
var wasmOpts []wasm.Option
if cast.ToBool(appOpts.Get("telemetry.enabled")) {
wasmOpts = append(wasmOpts, wasmkeeper.WithVMCacheMetrics(prometheus.DefaultRegisterer))
}
// add the custom wormhole query handler
wasmOpts = append(wasmOpts, wasmkeeper.WithQueryPlugins(wormholemodulekeeper.NewCustomQueryHandler(app.WormholeKeeper)))
// Move custom query of token factory to stargate, still use custom msg which is tfOpts[1]
bankBaseKeeper, ok := app.BankKeeper.(bankkeeper.BaseKeeper)
if !ok {
panic("Cannot cast bank keeper to bank basekeeper")
}
tfOpts := bindings.RegisterCustomPlugins(&bankBaseKeeper, &app.TokenFactoryKeeper)
wasmOpts = append(wasmOpts, tfOpts...)
return wasmOpts
}
var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string
// ModuleBasics defines the module BasicManager is in charge of setting up basic,
// non-dependant module elements, such as codec registration
// and genesis verification.
ModuleBasics = module.NewBasicManager(
auth.AppModuleBasic{},
genutil.AppModuleBasic{},
bank.AppModuleBasic{},
capability.AppModuleBasic{},
staking.AppModuleBasic{},
mint.AppModuleBasic{},
distr.AppModuleBasic{},
gov.NewAppModuleBasic(getGovProposalHandlers()...),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
slashing.AppModuleBasic{},
feegrantmodule.AppModuleBasic{},
ibc.AppModuleBasic{},
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
wormholemodule.AppModuleBasic{},
// this line is used by starport scaffolding # stargate/app/moduleBasic
wasm.AppModuleBasic{},
tokenfactory.AppModuleBasic{},
ibchooks.AppModuleBasic{},
packetforward.AppModuleBasic{},
ibccomposabilitymw.AppModuleBasic{},
)
// module account permissions
maccPerms = map[string][]string{
authtypes.FeeCollectorName: nil,
distrtypes.ModuleName: nil,
minttypes.ModuleName: {authtypes.Minter},
stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking},
stakingtypes.NotBondedPoolName: {authtypes.Burner, authtypes.Staking},
govtypes.ModuleName: {authtypes.Burner},
ibctransfertypes.ModuleName: {authtypes.Minter, authtypes.Burner},
wormholemoduletypes.ModuleName: nil,
// this line is used by starport scaffolding # stargate/app/maccPerms
wasm.ModuleName: {authtypes.Burner},
tokenfactorytypes.ModuleName: {authtypes.Minter, authtypes.Burner},
}
tokenFactoryCapabilities = []string{}
Upgrades = []Upgrade{V2_23_0_Upgrade}
)
var (
_ cosmoscmd.CosmosApp = (*App)(nil)
_ servertypes.Application = (*App)(nil)
)
func init() {
userHomeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
DefaultNodeHome = filepath.Join(userHomeDir, "."+Name)
}
// App extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions, as object
// capabilities aren't needed for testing.
type App struct {
*baseapp.BaseApp
cdc *codec.LegacyAmino
appCodec codec.Codec
interfaceRegistry types.InterfaceRegistry
invCheckPeriod uint
// keys to access the substores
keys map[string]*sdk.KVStoreKey
tkeys map[string]*sdk.TransientStoreKey
memKeys map[string]*sdk.MemoryStoreKey
// keepers
AccountKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
CapabilityKeeper *capabilitykeeper.Keeper
StakingKeeper stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
MintKeeper mintkeeper.Keeper
DistrKeeper distrkeeper.Keeper
GovKeeper govkeeper.Keeper
CrisisKeeper crisiskeeper.Keeper
UpgradeKeeper upgradekeeper.Keeper
ParamsKeeper paramskeeper.Keeper
IBCKeeper *ibckeeper.Keeper // IBC Keeper must be a pointer in the app, so we can SetRouter on it correctly
EvidenceKeeper evidencekeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
WormholeKeeper wormholemodulekeeper.Keeper
TokenFactoryKeeper tokenfactorykeeper.Keeper
// IBC modules
RawIcs20TransferAppModule transfer.AppModule
IBCHooksKeeper *ibchookskeeper.Keeper
TransferStack *ibccomposabilitymw.IBCMiddleware
Ics20WasmHooks *ibchooks.WasmHooks
HooksICS4Wrapper ibchooks.ICS4Middleware
PacketForwardKeeper *packetforwardkeeper.Keeper
IbcComposabilityMwKeeper *ibccomposabilitymwkeeper.Keeper
// this line is used by starport scaffolding # stargate/app/keeperDeclaration
wasmKeeper wasm.Keeper
ContractKeeper *wasmkeeper.PermissionedKeeper
scopedWasmKeeper capabilitykeeper.ScopedKeeper
// the module manager
mm *module.Manager
// module configurator
configurator module.Configurator
}
// New returns a reference to an initialized Gaia.
func New(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
skipUpgradeHeights map[int64]bool,
homePath string,
invCheckPeriod uint,
encodingConfig cosmoscmd.EncodingConfig,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) cosmoscmd.App {
appCodec := encodingConfig.Marshaler
cdc := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
bApp := baseapp.NewBaseApp(Name, logger, db, encodingConfig.TxConfig.TxDecoder(), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
keys := sdk.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, ibchost.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, ibctransfertypes.StoreKey, capabilitytypes.StoreKey,
wormholemoduletypes.StoreKey, ibccomposabilitytypes.StoreKey,
// this line is used by starport scaffolding # stargate/app/storeKey
wasm.StoreKey, tokenfactorytypes.StoreKey,
ibchookstypes.StoreKey, packetforwardtypes.StoreKey,
)
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
app := &App{
BaseApp: bApp,
cdc: cdc,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
}
app.ParamsKeeper = initParamsKeeper(appCodec, cdc, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
// set the BaseApp's parameter store
bApp.SetParamStore(app.ParamsKeeper.Subspace(baseapp.Paramspace).WithKeyTable(paramskeeper.ConsensusParamsKeyTable()))
// add capability keeper and ScopeToModule for ibc module
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
// grant capabilities for the ibc and ibc-transfer modules
app.ScopedIBCKeeper = app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
app.ScopedTransferKeeper = app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
// this line is used by starport scaffolding # stargate/app/scopedKeeper
app.scopedWasmKeeper = app.CapabilityKeeper.ScopeToModule(wasm.ModuleName)
// add keepers
app.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms,
)
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(),
)
app.WormholeKeeper = *wormholemodulekeeper.NewKeeper(
appCodec,
keys[wormholemoduletypes.StoreKey],
keys[wormholemoduletypes.MemStoreKey],
app.AccountKeeper,
app.BankKeeper,
)
stakingKeeper := stakingkeeper.NewKeeper(
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.WormholeKeeper, app.GetSubspace(stakingtypes.ModuleName),
)
app.MintKeeper = mintkeeper.NewKeeper(
appCodec, keys[minttypes.StoreKey], app.GetSubspace(minttypes.ModuleName), &stakingKeeper,
app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName,
)
app.DistrKeeper = distrkeeper.NewKeeper(
appCodec, keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, authtypes.FeeCollectorName, app.ModuleAccountAddrs(),
)
app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
)
app.CrisisKeeper = crisiskeeper.NewKeeper(
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
)
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp)
app.WormholeKeeper.SetUpgradeKeeper(app.UpgradeKeeper)
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.StakingKeeper = *stakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
)
// ... other modules keepers
// Create IBC Keeper
app.IBCKeeper = ibckeeper.NewKeeper(
appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, app.ScopedIBCKeeper,
)
app.WireICS20PreWasmKeeper(&app.WormholeKeeper)
// register the proposal types
govRouter := govtypes.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
// Create evidence Keeper for to register the IBC light client misbehaviour evidence route
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec, keys[evidencetypes.StoreKey], &app.StakingKeeper, app.SlashingKeeper,
)
// If evidence needs to be handled for the app, set routes in router here and seal
app.EvidenceKeeper = *evidenceKeeper
govRouter.AddRoute(wormholemoduletypes.RouterKey, wormholemodule.NewWormholeGovernanceProposalHandler(app.WormholeKeeper))
app.GovKeeper = govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter,
)
app.TokenFactoryKeeper = tokenfactorykeeper.NewKeeper(
app.keys[tokenfactorytypes.StoreKey],
app.GetSubspace(tokenfactorytypes.ModuleName),
app.AccountKeeper,
app.BankKeeper,
app.DistrKeeper,
tokenFactoryCapabilities,
)
// The last arguments can contain custom message handlers, and custom query handlers,
// if we want to allow any custom callbacks
supportedFeatures := "iterator,staking,stargate,wormhole,token_factory"
wasmDir := filepath.Join(homePath, "data")
// Instantiate wasm keeper with stubs for other modules as we do not need
// wasm to be able to write to other modules.
app.wasmKeeper = wasm.NewKeeper(
appCodec,
keys[wasm.StoreKey],
app.GetSubspace(wasm.ModuleName),
app.AccountKeeper,
app.BankKeeper,
app.StakingKeeper,
app.DistrKeeper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
app.scopedWasmKeeper,
app.TransferKeeper,
app.WormholeKeeper,
app.MsgServiceRouter(),
app.GRPCQueryRouter(),
wasmDir,
wasm.DefaultWasmConfig(),
// wasmConfig.ToWasmConfig(),
supportedFeatures,
GetWasmOpts(app, appOpts)...,
)
permissionedWasmKeeper := wasmkeeper.NewDefaultPermissionKeeper(app.wasmKeeper)
app.WormholeKeeper.SetWasmdKeeper(permissionedWasmKeeper)
// the wormhole module must be instantiated after the wasmd module
wormholeModule := wormholemodule.NewAppModule(appCodec, app.WormholeKeeper)
// this line is used by starport scaffolding # stargate/app/keeperDefinition
app.ContractKeeper = wasmkeeper.NewDefaultPermissionKeeper(app.wasmKeeper)
app.Ics20WasmHooks.ContractKeeper = app.ContractKeeper
app.IbcComposabilityMwKeeper.SetWasmKeeper(&app.wasmKeeper)
// Create static IBC router, add transfer route, then set and seal it
ibcRouter := ibcporttypes.NewRouter()
ibcRouter.AddRoute(ibctransfertypes.ModuleName, app.TransferStack).
AddRoute(wasm.ModuleName, wasm.NewIBCHandler(app.wasmKeeper, app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper))
// this line is used by starport scaffolding # ibc/app/router
app.IBCKeeper.SetRouter(ibcRouter)
//upgrade handlers
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
/**** Module Options ****/
// NOTE: we may consider parsing `appOpts` inside module constructors. For the moment
// we prefer to be more strict in what arguments the modules expect.
var skipGenesisInvariants = cast.ToBool(appOpts.Get(crisis.FlagSkipGenesisInvariants))
// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.mm = module.NewManager(
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
encodingConfig.TxConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper, nil),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.WormholeKeeper),
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
ibc.NewAppModule(app.IBCKeeper),
params.NewAppModule(app.ParamsKeeper),
app.RawIcs20TransferAppModule,
wormholeModule,
// this line is used by starport scaffolding # stargate/app/appModule
wasm.NewAppModule(appCodec, &app.wasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
tokenfactory.NewAppModule(app.TokenFactoryKeeper, app.AccountKeeper, app.BankKeeper),
ibchooks.NewAppModule(app.AccountKeeper),
packetforward.NewAppModule(app.PacketForwardKeeper),
ibccomposabilitymw.NewAppModule(app.IbcComposabilityMwKeeper),
)
// During begin block slashing happens after distr.BeginBlocker so that
// there is nothing left over in the validator fee pool, so as to keep the
// CanWithdrawInvariant invariant.
// NOTE: staking module is required if HistoricalEntries param > 0
app.mm.SetOrderBeginBlockers(
upgradetypes.ModuleName,
capabilitytypes.ModuleName,
minttypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
vestingtypes.ModuleName,
ibchost.ModuleName,
ibctransfertypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
govtypes.ModuleName,
crisistypes.ModuleName,
genutiltypes.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
wormholemoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/beginBlockers
wasm.ModuleName,
tokenfactorytypes.ModuleName,
ibchookstypes.ModuleName,
packetforwardtypes.ModuleName,
ibccomposabilitytypes.ModuleName,
)
app.mm.SetOrderEndBlockers(
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
vestingtypes.ModuleName,
minttypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
ibchost.ModuleName,
ibctransfertypes.ModuleName,
wormholemoduletypes.ModuleName,
// this line is used by starport scaffolding # stargate/app/endBlockers
wasm.ModuleName,
tokenfactorytypes.ModuleName,
ibchookstypes.ModuleName,
packetforwardtypes.ModuleName,
ibccomposabilitytypes.ModuleName,
)
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: Capability module must occur first so that it can initialize any capabilities
// so that other modules that want to create or claim capabilities afterwards in InitChain
// can do so safely.
// NOTE: The wormhole module must occur before staking so that the consensus
// guardian set is properly initialised before the staking module allocates
// voting power in its genesis handler
app.mm.SetOrderInitGenesis(
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
wormholemoduletypes.ModuleName,
stakingtypes.ModuleName,
vestingtypes.ModuleName,
slashingtypes.ModuleName,
govtypes.ModuleName,
minttypes.ModuleName,
crisistypes.ModuleName,
ibchost.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
ibctransfertypes.ModuleName,
feegrant.ModuleName,
// this line is used by starport scaffolding # stargate/app/initGenesis
wasm.ModuleName,
tokenfactorytypes.ModuleName,
ibchookstypes.ModuleName,
packetforwardtypes.ModuleName,
ibccomposabilitytypes.ModuleName,
)
app.mm.RegisterInvariants(&app.CrisisKeeper)
app.mm.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
app.mm.RegisterServices(app.configurator)
// initialize stores
app.MountKVStores(keys)
app.MountTransientStores(tkeys)
app.MountMemoryStores(memKeys)
// register upgrade
app.setupUpgradeHandlers(app.configurator)
// initialize BaseApp
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
anteHandlerSdk, 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)
}
wrappedAnteHandler := WrapAnteHandler(anteHandlerSdk, app.WormholeKeeper, app.IBCKeeper)
app.SetAnteHandler(wrappedAnteHandler)
app.SetEndBlocker(app.EndBlocker)
app.setupUpgradeStoreLoaders()
if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
tmos.Exit(err.Error())
}
}
return app
}
// Wrap the standard cosmos-sdk antehandlers with additional antehandlers:
// - wormhole allowlist antehandler
// - default ibc antehandler
func WrapAnteHandler(originalHandler sdk.AnteHandler, wormKeeper wormholemodulekeeper.Keeper, ibcKeeper *ibckeeper.Keeper) sdk.AnteHandler {
whHandler := wormholemoduleante.NewWormholeAllowlistDecorator(wormKeeper)
ibcHandler := ibcante.NewAnteDecorator(ibcKeeper)
newHandlers := sdk.ChainAnteDecorators(whHandler, ibcHandler)
return func(ctx sdk.Context, tx sdk.Tx, simulate bool) (sdk.Context, error) {
newCtx, err := originalHandler(ctx, tx, simulate)
if err != nil {
return newCtx, err
}
newCtx, err = newHandlers(newCtx, tx, simulate)
if err != nil {
return newCtx, err
}
return newCtx, err
}
}
// Name returns the name of the App
func (app *App) Name() string { return app.BaseApp.Name() }
// BeginBlocker application updates every begin block
func (app *App) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.mm.BeginBlock(ctx, req)
}
// EndBlocker application updates every end block
func (app *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req)
}
// InitChainer application update at chain initialization
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)
}
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
}
// LoadHeight loads a particular height
func (app *App) LoadHeight(height int64) error {
return app.LoadVersion(height)
}
// ModuleAccountAddrs returns all the app's module account addresses.
func (app *App) ModuleAccountAddrs() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range maccPerms {
modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
}
return modAccAddrs
}
// LegacyAmino returns SimApp's amino codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *App) LegacyAmino() *codec.LegacyAmino {
return app.cdc
}
// AppCodec returns Gaia's app codec.
//
// NOTE: This is solely to be used for testing purposes as it may be desirable
// for modules to register their own custom testing types.
func (app *App) AppCodec() codec.Codec {
return app.appCodec
}
// InterfaceRegistry returns Gaia's InterfaceRegistry
func (app *App) InterfaceRegistry() types.InterfaceRegistry {
return app.interfaceRegistry
}
// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *App) GetKey(storeKey string) *sdk.KVStoreKey {
return app.keys[storeKey]
}
// GetTKey returns the TransientStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *App) GetTKey(storeKey string) *sdk.TransientStoreKey {
return app.tkeys[storeKey]
}
// GetMemKey returns the MemStoreKey for the provided mem key.
//
// NOTE: This is solely used for testing purposes.
func (app *App) GetMemKey(storeKey string) *sdk.MemoryStoreKey {
return app.memKeys[storeKey]
}
// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *App) GetSubspace(moduleName string) paramstypes.Subspace {
subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
return subspace
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *App) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
clientCtx := apiSvr.ClientCtx
rpc.RegisterRoutes(clientCtx, apiSvr.Router)
// Register legacy tx routes.
authrest.RegisterTxRoutes(clientCtx, apiSvr.Router)
// Register new tx routes from grpc-gateway.
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// Register new tendermint queries routes from grpc-gateway.
tmservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// Register legacy and grpc-gateway routes for all modules.
ModuleBasics.RegisterRESTRoutes(clientCtx, apiSvr.Router)
ModuleBasics.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// register app's OpenAPI routes.
apiSvr.Router.Handle("/static/openapi.yml", http.FileServer(http.FS(docs.Docs)))
apiSvr.Router.HandleFunc("/", openapiconsole.Handler(Name, "/static/openapi.yml"))
}
// RegisterTxService implements the Application.RegisterTxService method.
func (app *App) RegisterTxService(clientCtx client.Context) {
authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}
// RegisterTendermintService implements the Application.RegisterTendermintService method.
func (app *App) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
}
func (app *App) GetWasmKeeper() *wasmkeeper.Keeper {
return &app.wasmKeeper
}
// GetMaccPerms returns a copy of the module account permissions
func GetMaccPerms() map[string][]string {
dupMaccPerms := make(map[string][]string)
for k, v := range maccPerms {
dupMaccPerms[k] = v
}
return dupMaccPerms
}
// initParamsKeeper init params keeper and its subspaces
func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey sdk.StoreKey) paramskeeper.Keeper {
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
paramsKeeper.Subspace(authtypes.ModuleName)
paramsKeeper.Subspace(banktypes.ModuleName)
paramsKeeper.Subspace(stakingtypes.ModuleName)
paramsKeeper.Subspace(minttypes.ModuleName)
paramsKeeper.Subspace(distrtypes.ModuleName)
paramsKeeper.Subspace(slashingtypes.ModuleName)
paramsKeeper.Subspace(govtypes.ModuleName).WithKeyTable(govtypes.ParamKeyTable())
paramsKeeper.Subspace(crisistypes.ModuleName)
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibchost.ModuleName)
paramsKeeper.Subspace(wormholemoduletypes.ModuleName)
// this line is used by starport scaffolding # stargate/app/paramSubspace
paramsKeeper.Subspace(wasm.ModuleName)
paramsKeeper.Subspace(tokenfactorytypes.ModuleName)
paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable())
return paramsKeeper
}
// WireICS20PreWasmKeeper Create the IBC Transfer Stack from bottom to top:
//
// * SendPacket. Originates from the transferKeeper and goes up the stack:
// transferKeeper.SendPacket -> ibc_hooks.SendPacket -> ibcComposabilityMw.SendPacket -> channel.SendPacket
// * RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way
// channel.RecvPacket -> ibcComposabilityMw.OnRecvPackate -> ibc_hooks.OnRecvPacket -> forward.OnRecvPacket -> transfer.OnRecvPacket
//
// Note that the forward middleware is only integrated on the "receive" direction.
// It can be safely skipped when sending.
//
// After this, the wasm keeper is required to be set on app.Ics20WasmHooks
func (app *App) WireICS20PreWasmKeeper(wk *wormholemodulekeeper.Keeper) {
// Configure the ibc composability mw keeper
ibcComposabilityMwKeeper := ibccomposabilitymwkeeper.NewKeeper(
app.appCodec,
app.keys[ibccomposabilitytypes.StoreKey],
nil, // Wasm keeper is set later
wk,
0,
time.Hour,
)
app.IbcComposabilityMwKeeper = ibcComposabilityMwKeeper
ibcComposabilityMwICS4Wrapper := ibccomposabilitymw.NewICS4Middleware(
app.IBCKeeper.ChannelKeeper,
ibcComposabilityMwKeeper,
)
// Configure the hooks keeper
ibcHooksKeeper := ibchookskeeper.NewKeeper(
app.keys[ibchookstypes.StoreKey],
)
app.IBCHooksKeeper = &ibcHooksKeeper
// Setup the ICS4Wrapper used by the hooks middleware
wormPrefix := sdk.GetConfig().GetBech32AccountAddrPrefix()
wasmHooks := ibchooks.NewWasmHooks(&ibcHooksKeeper, nil, wormPrefix) // The contract keeper needs to be set later
app.Ics20WasmHooks = &wasmHooks
app.HooksICS4Wrapper = ibchooks.NewICS4Middleware(
ibcComposabilityMwICS4Wrapper,
app.Ics20WasmHooks,
)
// Create Transfer Keepers
transferKeeper := ibctransferkeeper.NewKeeper(
app.appCodec,
app.keys[ibctransfertypes.StoreKey],
app.GetSubspace(ibctransfertypes.ModuleName),
// The ICS4Wrapper is replaced by the HooksICS4Wrapper instead of the channel
app.HooksICS4Wrapper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
app.AccountKeeper,
app.BankKeeper,
app.ScopedTransferKeeper,
)
app.TransferKeeper = transferKeeper
app.RawIcs20TransferAppModule = transfer.NewAppModule(app.TransferKeeper)
// Packet Forward Middleware
// Initialize packet forward middleware router
app.PacketForwardKeeper = packetforwardkeeper.NewKeeper(
app.appCodec,
app.keys[packetforwardtypes.StoreKey],
app.GetSubspace(packetforwardtypes.ModuleName),
app.TransferKeeper,
app.IBCKeeper.ChannelKeeper,
app.DistrKeeper,
app.BankKeeper,
// The ICS4Wrapper is replaced by the HooksICS4Wrapper instead of the channel so that sending can be overridden by the middleware
app.HooksICS4Wrapper,
)
// Set up transfer stack
// channel.RecvPacket -> ibcComposabilityMw.OnRecvPacket -> ibc_hooks.OnRecvPacket -> forward.OnRecvPacket -> transfer.OnRecvPacket
packetForwardMiddleware := packetforward.NewIBCMiddleware(
transfer.NewIBCModule(app.TransferKeeper),
app.PacketForwardKeeper,
0,
packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp,
packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp,
)
// Hooks Middleware
hooksTransferModule := ibchooks.NewIBCMiddleware(packetForwardMiddleware, &app.HooksICS4Wrapper)
// IBC Composability Middleware
ibcComposabilityMiddleware := ibccomposabilitymw.NewIBCMiddleware(&hooksTransferModule, &ibcComposabilityMwICS4Wrapper, ibcComposabilityMwKeeper)
app.TransferStack = &ibcComposabilityMiddleware
}
// configure store loader that checks if version == upgradeHeight and applies store upgrades
func (app *App) setupUpgradeStoreLoaders() {
upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
if err != nil {
panic("failed to read upgrade info from disk" + err.Error())
}
if app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) {
return
}
for _, upgrade := range Upgrades {
if upgradeInfo.Name == upgrade.UpgradeName {
storeUpgrades := upgrade.StoreUpgrades
app.SetStoreLoader(
upgradetypes.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades),
)
}
}
}
func (app *App) setupUpgradeHandlers(cfg module.Configurator) {
for _, upgrade := range Upgrades {
app.UpgradeKeeper.SetUpgradeHandler(
upgrade.UpgradeName,
upgrade.CreateUpgradeHandler(
app.mm,
cfg,
app,
),
)
}
}
// BaseAppParamManager defines an interrace that BaseApp is expected to fullfil
// that allows upgrade handlers to modify BaseApp parameters.
type BaseAppParamManager interface {
GetConsensusParams(ctx sdk.Context) *tmproto.ConsensusParams
StoreConsensusParams(ctx sdk.Context, cp *tmproto.ConsensusParams)
}
// Upgrade defines a struct containing necessary fields that a SoftwareUpgradeProposal
// must have written, in order for the state migration to go smoothly.
// An upgrade must implement this struct, and then set it in the app.go.
// The app.go will then define the handler.
type Upgrade struct {
// Upgrade version name, for the upgrade handler, e.g. `v7`
UpgradeName string
// CreateUpgradeHandler defines the function that creates an upgrade handler
CreateUpgradeHandler func(
*module.Manager,
module.Configurator,
*App,
) upgradetypes.UpgradeHandler
// Store upgrades, should be used for any new modules introduced, new modules deleted, or store names renamed.
StoreUpgrades store.StoreUpgrades
}