mukan-ibc/modules/apps/callbacks/testing/simapp/app.go
Mukan Erkin Törük 88dd97a9f8
Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:22 +03:00

880 lines
35 KiB
Go

package simapp
import (
"encoding/json"
"fmt"
"io"
"maps"
"os"
"path/filepath"
dbm "github.com/cosmos/cosmos-db"
"github.com/cosmos/gogoproto/proto"
"github.com/spf13/cast"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"cosmossdk.io/x/tx/signing"
"cosmossdk.io/x/upgrade"
upgradekeeper "cosmossdk.io/x/upgrade/keeper"
upgradetypes "cosmossdk.io/x/upgrade/types"
"git.cw.tr/mukan-network/mukan-sdk/baseapp"
"git.cw.tr/mukan-network/mukan-sdk/client"
"git.cw.tr/mukan-network/mukan-sdk/client/flags"
"git.cw.tr/mukan-network/mukan-sdk/client/grpc/cmtservice"
nodeservice "git.cw.tr/mukan-network/mukan-sdk/client/grpc/node"
"git.cw.tr/mukan-network/mukan-sdk/codec"
"git.cw.tr/mukan-network/mukan-sdk/codec/address"
"git.cw.tr/mukan-network/mukan-sdk/codec/types"
"git.cw.tr/mukan-network/mukan-sdk/runtime"
"git.cw.tr/mukan-network/mukan-sdk/server"
"git.cw.tr/mukan-network/mukan-sdk/server/api"
"git.cw.tr/mukan-network/mukan-sdk/server/config"
servertypes "git.cw.tr/mukan-network/mukan-sdk/server/types"
"git.cw.tr/mukan-network/mukan-sdk/std"
"git.cw.tr/mukan-network/mukan-sdk/testutil/testdata/testpb"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
"git.cw.tr/mukan-network/mukan-sdk/types/module"
"git.cw.tr/mukan-network/mukan-sdk/types/msgservice"
"git.cw.tr/mukan-network/mukan-sdk/version"
"git.cw.tr/mukan-network/mukan-sdk/x/auth"
"git.cw.tr/mukan-network/mukan-sdk/x/auth/ante"
authcodec "git.cw.tr/mukan-network/mukan-sdk/x/auth/codec"
authkeeper "git.cw.tr/mukan-network/mukan-sdk/x/auth/keeper"
"git.cw.tr/mukan-network/mukan-sdk/x/auth/posthandler"
authsims "git.cw.tr/mukan-network/mukan-sdk/x/auth/simulation"
authtx "git.cw.tr/mukan-network/mukan-sdk/x/auth/tx"
authtypes "git.cw.tr/mukan-network/mukan-sdk/x/auth/types"
"git.cw.tr/mukan-network/mukan-sdk/x/auth/vesting"
vestingtypes "git.cw.tr/mukan-network/mukan-sdk/x/auth/vesting/types"
"git.cw.tr/mukan-network/mukan-sdk/x/bank"
bankkeeper "git.cw.tr/mukan-network/mukan-sdk/x/bank/keeper"
banktypes "git.cw.tr/mukan-network/mukan-sdk/x/bank/types"
"git.cw.tr/mukan-network/mukan-sdk/x/consensus"
consensusparamkeeper "git.cw.tr/mukan-network/mukan-sdk/x/consensus/keeper"
consensusparamtypes "git.cw.tr/mukan-network/mukan-sdk/x/consensus/types"
distr "git.cw.tr/mukan-network/mukan-sdk/x/distribution"
distrkeeper "git.cw.tr/mukan-network/mukan-sdk/x/distribution/keeper"
distrtypes "git.cw.tr/mukan-network/mukan-sdk/x/distribution/types"
"git.cw.tr/mukan-network/mukan-sdk/x/genutil"
genutiltypes "git.cw.tr/mukan-network/mukan-sdk/x/genutil/types"
"git.cw.tr/mukan-network/mukan-sdk/x/gov"
govclient "git.cw.tr/mukan-network/mukan-sdk/x/gov/client"
govkeeper "git.cw.tr/mukan-network/mukan-sdk/x/gov/keeper"
govtypes "git.cw.tr/mukan-network/mukan-sdk/x/gov/types"
"git.cw.tr/mukan-network/mukan-sdk/x/mint"
mintkeeper "git.cw.tr/mukan-network/mukan-sdk/x/mint/keeper"
minttypes "git.cw.tr/mukan-network/mukan-sdk/x/mint/types"
"git.cw.tr/mukan-network/mukan-sdk/x/params"
paramsclient "git.cw.tr/mukan-network/mukan-sdk/x/params/client"
paramskeeper "git.cw.tr/mukan-network/mukan-sdk/x/params/keeper"
paramstypes "git.cw.tr/mukan-network/mukan-sdk/x/params/types"
"git.cw.tr/mukan-network/mukan-sdk/x/slashing"
slashingkeeper "git.cw.tr/mukan-network/mukan-sdk/x/slashing/keeper"
slashingtypes "git.cw.tr/mukan-network/mukan-sdk/x/slashing/types"
"git.cw.tr/mukan-network/mukan-sdk/x/staking"
stakingkeeper "git.cw.tr/mukan-network/mukan-sdk/x/staking/keeper"
stakingtypes "git.cw.tr/mukan-network/mukan-sdk/x/staking/types"
abci "git.cw.tr/mukan-network/mukan-consensus/abci/types"
ica "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts"
icacontroller "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller"
icacontrollerkeeper "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller/keeper"
icacontrollertypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/controller/types"
icahost "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/host"
icahostkeeper "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/host/keeper"
icahosttypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/host/types"
icatypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/27-interchain-accounts/types"
ibccallbacks "git.cw.tr/mukan-network/mukan-ibc/modules/apps/callbacks"
ibccallbacksv2 "git.cw.tr/mukan-network/mukan-ibc/modules/apps/callbacks/v2"
"git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer"
ibctransferkeeper "git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/keeper"
ibctransfertypes "git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/types"
transferv2 "git.cw.tr/mukan-network/mukan-ibc/modules/apps/transfer/v2"
ibc "git.cw.tr/mukan-network/mukan-ibc/modules/core"
porttypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/05-port/types"
ibcapi "git.cw.tr/mukan-network/mukan-ibc/modules/core/api"
ibcexported "git.cw.tr/mukan-network/mukan-ibc/modules/core/exported"
ibckeeper "git.cw.tr/mukan-network/mukan-ibc/modules/core/keeper"
solomachine "git.cw.tr/mukan-network/mukan-ibc/modules/light-clients/06-solomachine"
ibctm "git.cw.tr/mukan-network/mukan-ibc/modules/light-clients/07-tendermint"
ibcmock "git.cw.tr/mukan-network/mukan-ibc/testing/mock"
)
const appName = "SimApp"
var (
// DefaultNodeHome default home directories for the application daemon
DefaultNodeHome string
// 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},
icatypes.ModuleName: nil,
ibcmock.ModuleName: nil,
}
)
var (
_ runtime.AppI = (*SimApp)(nil)
_ servertypes.Application = (*SimApp)(nil)
)
// SimApp extends an ABCI application, but with most of its parameters exported.
// They are exported for convenience in creating helper functions.
type SimApp struct {
*baseapp.BaseApp
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
txConfig client.TxConfig
interfaceRegistry types.InterfaceRegistry
// keys to access the substores
keys map[string]*storetypes.KVStoreKey
tkeys map[string]*storetypes.TransientStoreKey
memKeys map[string]*storetypes.MemoryStoreKey
// keepers
AccountKeeper authkeeper.AccountKeeper
BankKeeper bankkeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
SlashingKeeper slashingkeeper.Keeper
MintKeeper mintkeeper.Keeper
DistrKeeper distrkeeper.Keeper
GovKeeper govkeeper.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
ICAControllerKeeper icacontrollerkeeper.Keeper
ICAHostKeeper icahostkeeper.Keeper
TransferKeeper ibctransferkeeper.Keeper
ConsensusParamsKeeper consensusparamkeeper.Keeper
// mock contract keeper used for testing
MockContractKeeper *ContractKeeper
// make IBC modules public for test purposes
// these modules are never directly routed to by the IBC Router
ICAAuthModule ibcmock.IBCModule
// the module manager
ModuleManager *module.Manager
BasicModuleManager module.BasicManager
// simulation manager
simulationManager *module.SimulationManager
// module configurator
configurator module.Configurator
}
func init() {
userHomeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
DefaultNodeHome = filepath.Join(userHomeDir, ".simapp")
}
// NewSimApp returns a reference to an initialized SimApp.
func NewSimApp(
logger log.Logger,
db dbm.DB,
traceStore io.Writer,
loadLatest bool,
appOpts servertypes.AppOptions,
baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
interfaceRegistry, _ := types.NewInterfaceRegistryWithOptions(types.InterfaceRegistryOptions{
ProtoFiles: proto.HybridResolver,
SigningOptions: signing.Options{
AddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32AccountAddrPrefix(),
},
ValidatorAddressCodec: address.Bech32Codec{
Bech32Prefix: sdk.GetConfig().GetBech32ValidatorAddrPrefix(),
},
},
})
appCodec := codec.NewProtoCodec(interfaceRegistry)
legacyAmino := codec.NewLegacyAmino()
txConfig := authtx.NewTxConfig(appCodec, authtx.DefaultSignModes)
std.RegisterLegacyAminoCodec(legacyAmino)
std.RegisterInterfaces(interfaceRegistry)
// Below we could construct and set an application specific mempool and
// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
// already set in the SDK's BaseApp, this shows an example of how to override
// them.
//
// Example:
//
// bApp := baseapp.NewBaseApp(...)
// nonceMempool := mempool.NewSenderNonceMempool()
// abciPropHandler := NewDefaultProposalHandler(nonceMempool, bApp)
//
// bApp.SetMempool(nonceMempool)
// bApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
// bApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
//
// Alternatively, you can construct BaseApp options, append those to
// baseAppOptions and pass them to NewBaseApp.
//
// Example:
//
// prepareOpt = func(app *baseapp.BaseApp) {
// abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
// app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
// }
// baseAppOptions = append(baseAppOptions, prepareOpt)
bApp := baseapp.NewBaseApp(appName, logger, db, txConfig.TxDecoder(), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
bApp.SetTxEncoder(txConfig.TxEncoder())
keys := storetypes.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, ibcexported.StoreKey, upgradetypes.StoreKey,
ibctransfertypes.StoreKey, icacontrollertypes.StoreKey, icahosttypes.StoreKey,
consensusparamtypes.StoreKey,
)
// register streaming services
if err := bApp.RegisterStreamingServices(appOpts, keys); err != nil {
panic(err)
}
tkeys := storetypes.NewTransientStoreKeys(paramstypes.TStoreKey)
memKeys := storetypes.NewMemoryStoreKeys(ibcmock.MemStoreKey)
app := &SimApp{
BaseApp: bApp,
legacyAmino: legacyAmino,
appCodec: appCodec,
txConfig: txConfig,
interfaceRegistry: interfaceRegistry,
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
}
app.ParamsKeeper = initParamsKeeper(appCodec, legacyAmino, keys[paramstypes.StoreKey], tkeys[paramstypes.TStoreKey])
// set the BaseApp's parameter store
app.ConsensusParamsKeeper = consensusparamkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[consensusparamtypes.StoreKey]), authtypes.NewModuleAddress(govtypes.ModuleName).String(), runtime.EventService{})
bApp.SetParamStore(app.ConsensusParamsKeeper.ParamsStore)
// SDK module keepers
// add keepers
app.AccountKeeper = authkeeper.NewAccountKeeper(appCodec, runtime.NewKVStoreService(keys[authtypes.StoreKey]), authtypes.ProtoBaseAccount, maccPerms, authcodec.NewBech32Codec(sdk.Bech32MainPrefix), sdk.Bech32MainPrefix, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec,
runtime.NewKVStoreService(keys[banktypes.StoreKey]),
app.AccountKeeper,
BlockedAddresses(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
logger,
)
app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(), authcodec.NewBech32Codec(sdk.Bech32PrefixValAddr), authcodec.NewBech32Codec(sdk.Bech32PrefixConsAddr),
)
app.MintKeeper = mintkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.DistrKeeper = distrkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[distrtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.StakingKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, legacyAmino, runtime.NewKVStoreService(keys[slashingtypes.StoreKey]), app.StakingKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
// register the staking hooks
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
app.StakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
)
// get skipUpgradeHeights from the app options
skipUpgradeHeights := map[int64]bool{}
for _, h := range cast.ToIntSlice(appOpts.Get(server.FlagUnsafeSkipUpgrades)) {
skipUpgradeHeights[int64(h)] = true
}
homePath := cast.ToString(appOpts.Get(flags.FlagHome))
// set the governance module account as the authority for conducting upgrades
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, runtime.NewKVStoreService(keys[upgradetypes.StoreKey]), appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.IBCKeeper = ibckeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[ibcexported.StoreKey]), app.GetSubspace(ibcexported.ModuleName), app.UpgradeKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
// NOTE: The mock ContractKeeper is only created for testing.
// Real applications should not use the mock ContractKeeper
app.MockContractKeeper = NewContractKeeper(memKeys[ibcmock.MemStoreKey])
govConfig := govtypes.DefaultConfig()
/*
Example of setting gov params:
govConfig.MaxMetadataLen = 10000
*/
govKeeper := govkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[govtypes.StoreKey]), app.AccountKeeper, app.BankKeeper,
app.StakingKeeper, app.DistrKeeper, app.MsgServiceRouter(), govConfig, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(
// register the governance hooks
),
)
// ICA Controller keeper
app.ICAControllerKeeper = icacontrollerkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[icacontrollertypes.StoreKey]), app.GetSubspace(icacontrollertypes.SubModuleName),
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ChannelKeeper,
app.MsgServiceRouter(),
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
// ICA Host keeper
app.ICAHostKeeper = icahostkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[icahosttypes.StoreKey]), app.GetSubspace(icahosttypes.SubModuleName),
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ChannelKeeper,
app.AccountKeeper, app.MsgServiceRouter(),
app.GRPCQueryRouter(), authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
// Create IBC Router
ibcRouter := porttypes.NewRouter()
ibcRouterV2 := ibcapi.NewRouter()
// Middleware Stacks
maxCallbackGas := uint64(1_000_000)
// Create Transfer Keeper
// NOTE: the Transfer Keeper's ICS4Wrapper can later be replaced.
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[ibctransfertypes.StoreKey]), app.GetSubspace(ibctransfertypes.ModuleName),
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ChannelKeeper,
app.MsgServiceRouter(),
app.AccountKeeper, app.BankKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
// Mock Module Stack
// Mock Module setup for testing IBC and also acts as the interchain accounts authentication module
// NOTE: the IBC mock keeper and application module is used only for testing core IBC. Do
// not replicate if you do not need to test core IBC or light clients.
mockModule := ibcmock.NewAppModule()
// The mock module is used for testing IBC
mockIBCModule := ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp(ibcmock.ModuleName))
ibcRouter.AddRoute(ibcmock.ModuleName, mockIBCModule)
// Create Transfer Stack
// SendPacket, since it is originating from the application to core IBC:
// transferKeeper.SendPacket -> callbacks.SendPacket -> channel.SendPacket
// RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way
// channel.RecvPacket -> callbacks.OnRecvPacket -> transfer.OnRecvPacket
// transfer stack contains (from top to bottom):
// - IBC Callbacks Middleware
// - Transfer
// create IBC module from bottom to top of stack
var transferStack porttypes.IBCModule
transferStack = transfer.NewIBCModule(app.TransferKeeper)
transferStack = ibccallbacks.NewIBCMiddleware(transferStack, app.IBCKeeper.ChannelKeeper, app.MockContractKeeper, maxCallbackGas)
var transferICS4Wrapper porttypes.ICS4Wrapper
transferICS4Wrapper, ok := transferStack.(porttypes.ICS4Wrapper)
if !ok {
panic(fmt.Errorf("cannot convert %T to %T", transferStack, transferICS4Wrapper))
}
// Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the transfer keeper
app.TransferKeeper.WithICS4Wrapper(transferICS4Wrapper)
// Add transfer stack to IBC Router
ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack)
// Create Interchain Accounts Stack
// SendPacket, since it is originating from the application to core IBC:
// icaControllerKeeper.SendTx -> callbacks.SendPacket -> channel.SendPacket
// initialize ICA module with mock module as the authentication module on the controller side
var icaControllerStack porttypes.IBCModule
icaControllerStack = ibcmock.NewIBCModule(&mockModule, ibcmock.NewIBCApp(""))
app.ICAAuthModule, ok = icaControllerStack.(ibcmock.IBCModule)
if !ok {
panic(fmt.Errorf("cannot convert %T to %T", icaControllerStack, app.ICAAuthModule))
}
icaControllerStack = icacontroller.NewIBCMiddlewareWithAuth(icaControllerStack, app.ICAControllerKeeper)
icaControllerStack = ibccallbacks.NewIBCMiddleware(icaControllerStack, app.IBCKeeper.ChannelKeeper, app.MockContractKeeper, maxCallbackGas)
var icaICS4Wrapper porttypes.ICS4Wrapper
icaICS4Wrapper, ok = icaControllerStack.(porttypes.ICS4Wrapper)
if !ok {
panic(fmt.Errorf("cannot convert %T to %T", icaControllerStack, icaICS4Wrapper))
}
// Since the callbacks middleware itself is an ics4wrapper, it needs to be passed to the ica controller keeper
app.ICAControllerKeeper.WithICS4Wrapper(icaICS4Wrapper)
// RecvPacket, message that originates from core IBC and goes down to app, the flow is:
// channel.RecvPacket -> icaHost.OnRecvPacket
var icaHostStack porttypes.IBCModule = icahost.NewIBCModule(app.ICAHostKeeper)
// Add host, controller & ica auth modules to IBC router
ibcRouter.
AddRoute(icacontrollertypes.SubModuleName, icaControllerStack).
AddRoute(icahosttypes.SubModuleName, icaHostStack).
AddRoute(ibcmock.ModuleName+icacontrollertypes.SubModuleName, icaControllerStack) // ica with mock auth module stack route to ica (top level of middleware stack)
// OnRecvPacket, message that originates from core IBC and goes down to app, the flow is the otherway
// channel.RecvPacket -> callbacks.OnRecvPacket -> mockModule.OnRecvPacket
// OnAcknowledgementPacket flow:
// mockModule.OnAcknowledgementPacket -> callbacks.OnAcknowledgementPacket -> channel.OnAcknowledgementPacket
// add transfer v2 module wrapped by callbacks v2 middleware
cbTransferModulev2 := ibccallbacksv2.NewIBCMiddleware(transferv2.NewIBCModule(app.TransferKeeper), app.IBCKeeper.ChannelKeeperV2, app.MockContractKeeper, app.IBCKeeper.ChannelKeeperV2, maxCallbackGas)
ibcRouterV2.AddRoute(ibctransfertypes.PortID, cbTransferModulev2)
// Seal the IBC Router
app.IBCKeeper.SetRouter(ibcRouter)
app.IBCKeeper.SetRouterV2(ibcRouterV2)
clientKeeper := app.IBCKeeper.ClientKeeper
storeProvider := app.IBCKeeper.ClientKeeper.GetStoreProvider()
tmLightClientModule := ibctm.NewLightClientModule(appCodec, storeProvider)
clientKeeper.AddRoute(ibctm.ModuleName, &tmLightClientModule)
smLightClientModule := solomachine.NewLightClientModule(appCodec, storeProvider)
clientKeeper.AddRoute(solomachine.ModuleName, &smLightClientModule)
// **** Module Options ****
// NOTE: Any module instantiated in the module manager that is later modified
// must be passed by reference here.
app.ModuleManager = module.NewManager(
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app,
txConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper, app.GetSubspace(banktypes.ModuleName)),
gov.NewAppModule(appCodec, &app.GovKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(govtypes.ModuleName)),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil, app.GetSubspace(minttypes.ModuleName)),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(slashingtypes.ModuleName), app.interfaceRegistry),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.GetSubspace(distrtypes.ModuleName)),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName)),
upgrade.NewAppModule(app.UpgradeKeeper, app.AccountKeeper.AddressCodec()),
params.NewAppModule(app.ParamsKeeper),
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
// IBC modules
ibc.NewAppModule(app.IBCKeeper),
transfer.NewAppModule(app.TransferKeeper),
ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper),
mockModule,
// IBC light clients
ibctm.NewAppModule(tmLightClientModule),
solomachine.NewAppModule(smLightClientModule),
)
// BasicModuleManager defines the module BasicManager is in charge of setting up basic,
// non-dependant module elements, such as codec registration and genesis verification.
// By default it is composed of all the module from the module manager.
// Additionally, app module basics can be overwritten by passing them as argument.
app.BasicModuleManager = module.NewBasicManagerFromManager(
app.ModuleManager,
map[string]module.AppModuleBasic{
genutiltypes.ModuleName: genutil.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
govtypes.ModuleName: gov.NewAppModuleBasic(
[]govclient.ProposalHandler{
paramsclient.ProposalHandler,
},
),
})
app.BasicModuleManager.RegisterLegacyAminoCodec(legacyAmino)
app.BasicModuleManager.RegisterInterfaces(interfaceRegistry)
// NOTE: upgrade module is required to be prioritized
app.ModuleManager.SetOrderPreBlockers(
upgradetypes.ModuleName,
authtypes.ModuleName,
)
// 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.ModuleManager.SetOrderBeginBlockers(
minttypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
stakingtypes.ModuleName,
ibcexported.ModuleName,
ibctransfertypes.ModuleName,
genutiltypes.ModuleName,
icatypes.ModuleName,
ibcmock.ModuleName,
)
app.ModuleManager.SetOrderEndBlockers(
govtypes.ModuleName,
stakingtypes.ModuleName,
ibcexported.ModuleName,
ibctransfertypes.ModuleName,
genutiltypes.ModuleName,
icatypes.ModuleName,
ibcmock.ModuleName,
)
// NOTE: The genutils module must occur after staking so that pools are
// properly initialized with tokens from genesis accounts.
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
genesisModuleOrder := []string{
authtypes.ModuleName,
banktypes.ModuleName, distrtypes.ModuleName, stakingtypes.ModuleName,
slashingtypes.ModuleName, govtypes.ModuleName, minttypes.ModuleName,
ibcexported.ModuleName, genutiltypes.ModuleName, ibctransfertypes.ModuleName,
icatypes.ModuleName, ibcmock.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
vestingtypes.ModuleName, consensusparamtypes.ModuleName,
}
app.ModuleManager.SetOrderInitGenesis(genesisModuleOrder...)
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)
// Uncomment if you want to set a custom migration order here.
// app.ModuleManager.SetOrderMigrations(custom order)
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
err := app.ModuleManager.RegisterServices(app.configurator)
if err != nil {
panic(err)
}
// add test gRPC service for testing gRPC queries in isolation
testpb.RegisterQueryServer(app.GRPCQueryRouter(), testpb.QueryImpl{})
// create the simulation manager and define the order of the modules for deterministic simulations
//
// NOTE: this is not required apps that don't use the simulator for fuzz testing
// transactions
overrideModules := map[string]module.AppModuleSimulation{
authtypes.ModuleName: auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts, app.GetSubspace(authtypes.ModuleName)),
}
app.simulationManager = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)
app.simulationManager.RegisterStoreDecoders()
// initialize stores
app.MountKVStores(keys)
app.MountTransientStores(tkeys)
app.MountMemoryStores(memKeys)
// initialize BaseApp
app.SetInitChainer(app.InitChainer)
app.SetPreBlocker(app.PreBlocker)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
app.setAnteHandler(txConfig)
// In v0.46, the SDK introduces _postHandlers_. PostHandlers are like
// antehandlers, but are run _after_ the `runMsgs` execution. They are also
// defined as a chain, and have the same signature as antehandlers.
//
// In baseapp, postHandlers are run in the same store branch as `runMsgs`,
// meaning that both `runMsgs` and `postHandler` state will be committed if
// both are successful, and both will be reverted if any of the two fails.
//
// The SDK exposes a default postHandlers chain, which is comprised of only
// one decorator: the Transaction Tips decorator. However, some chains do
// not need it by default, so feel free to comment the next line if you do
// not need tips.
// To read more about tips:
// https://docs.cosmos.network/main/core/tips.html
//
// Please note that changing any of the anteHandler or postHandler chain is
// likely to be a state-machine breaking change, which needs a coordinated
// upgrade.
app.setPostHandler()
// At startup, after all modules have been registered, check that all proto
// annotations are correct.
protoFiles, err := proto.MergedRegistry()
if err != nil {
panic(err)
}
err = msgservice.ValidateProtoAnnotations(protoFiles)
if err != nil {
// Once we switch to using protoreflect-based antehandlers, we might
// want to panic here instead of logging a warning.
_, err := fmt.Fprintln(os.Stderr, err.Error())
if err != nil {
fmt.Println("could not write to stderr")
}
}
if loadLatest {
if err := app.LoadLatestVersion(); err != nil {
panic(fmt.Errorf("error loading last version: %w", err))
}
}
return app
}
func (app *SimApp) setAnteHandler(txConfig client.TxConfig) {
anteHandler, err := NewAnteHandler(
HandlerOptions{
ante.HandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
SignModeHandler: txConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
app.IBCKeeper,
},
)
if err != nil {
panic(err)
}
// Set the AnteHandler for the app
app.SetAnteHandler(anteHandler)
}
func (app *SimApp) setPostHandler() {
postHandler, err := posthandler.NewPostHandler(
posthandler.HandlerOptions{},
)
if err != nil {
panic(err)
}
app.SetPostHandler(postHandler)
}
// Name returns the name of the App
func (app *SimApp) Name() string { return app.BaseApp.Name() }
// PreBlocker application updates every pre block
func (app *SimApp) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) {
return app.ModuleManager.PreBlock(ctx)
}
// BeginBlocker application updates every begin block
func (app *SimApp) BeginBlocker(ctx sdk.Context) (sdk.BeginBlock, error) {
return app.ModuleManager.BeginBlock(ctx)
}
// EndBlocker application updates every end block
func (app *SimApp) EndBlocker(ctx sdk.Context) (sdk.EndBlock, error) {
return app.ModuleManager.EndBlock(ctx)
}
// Configurator returns the configurator for the app
func (app *SimApp) Configurator() module.Configurator {
return app.configurator
}
// InitChainer application update at chain initialization
func (app *SimApp) InitChainer(ctx sdk.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
var genesisState GenesisState
if err := json.Unmarshal(req.AppStateBytes, &genesisState); err != nil {
panic(err)
}
if err := app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap()); err != nil {
panic(err)
}
return app.ModuleManager.InitGenesis(ctx, app.appCodec, genesisState)
}
// LoadHeight loads a particular height
func (app *SimApp) LoadHeight(height int64) error {
return app.LoadVersion(height)
}
// 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 *SimApp) LegacyAmino() *codec.LegacyAmino {
return app.legacyAmino
}
// AppCodec returns SimApp'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 *SimApp) AppCodec() codec.Codec {
return app.appCodec
}
// InterfaceRegistry returns SimApp's InterfaceRegistry
func (app *SimApp) InterfaceRegistry() types.InterfaceRegistry {
return app.interfaceRegistry
}
// TxConfig returns SimApp's TxConfig
func (app *SimApp) TxConfig() client.TxConfig {
return app.txConfig
}
// DefaultGenesis returns a default genesis from the registered AppModuleBasic's.
func (app *SimApp) DefaultGenesis() map[string]json.RawMessage {
return app.BasicModuleManager.DefaultGenesis(app.appCodec)
}
// GetKey returns the KVStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp) GetKey(storeKey string) *storetypes.KVStoreKey {
return app.keys[storeKey]
}
// GetStoreKeys returns all the stored store keys.
func (app *SimApp) GetStoreKeys() []storetypes.StoreKey {
keys := make([]storetypes.StoreKey, 0, len(app.keys))
for _, key := range app.keys {
keys = append(keys, key)
}
return keys
}
// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp) GetSubspace(moduleName string) paramstypes.Subspace {
subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
return subspace
}
// SimulationManager implements the SimulationApp interface
func (app *SimApp) SimulationManager() *module.SimulationManager {
return app.simulationManager
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *SimApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
clientCtx := apiSvr.ClientCtx
// Register new tx routes from grpc-gateway.
authtx.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// Register new CometBFT queries routes from grpc-gateway.
cmtservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// Register node gRPC service for grpc-gateway.
nodeservice.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// Register grpc-gateway routes for all modules.
app.BasicModuleManager.RegisterGRPCGatewayRoutes(clientCtx, apiSvr.GRPCGatewayRouter)
// register swagger API from root so that other applications can override easily
if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
panic(err)
}
}
// RegisterTxService implements the Application.RegisterTxService method.
func (app *SimApp) RegisterTxService(clientCtx client.Context) {
authtx.RegisterTxService(app.GRPCQueryRouter(), clientCtx, app.Simulate, app.interfaceRegistry)
}
// RegisterTendermintService implements the Application.RegisterTendermintService method.
func (app *SimApp) RegisterTendermintService(clientCtx client.Context) {
cmtApp := server.NewCometABCIWrapper(app)
cmtservice.RegisterTendermintService(
clientCtx,
app.GRPCQueryRouter(),
app.interfaceRegistry,
cmtApp.Query,
)
}
func (app *SimApp) RegisterNodeService(clientCtx client.Context, cfg config.Config) {
nodeservice.RegisterNodeService(clientCtx, app.GRPCQueryRouter(), cfg)
}
// GetMaccPerms returns a copy of the module account permissions
//
// NOTE: This is solely to be used for testing purposes.
func GetMaccPerms() map[string][]string {
dupMaccPerms := make(map[string][]string)
maps.Copy(dupMaccPerms, maccPerms)
return dupMaccPerms
}
// BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range GetMaccPerms() {
modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
}
// allow the following addresses to receive funds
delete(modAccAddrs, authtypes.NewModuleAddress(govtypes.ModuleName).String())
delete(modAccAddrs, authtypes.NewModuleAddress(ibcmock.ModuleName).String())
return modAccAddrs
}
// initParamsKeeper init params keeper and its subspaces
func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper {
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
// TODO: ibc module subspaces can be removed after migration of params
// https://github.com/cosmos/ibc-go/issues/2010
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
paramsKeeper.Subspace(ibcexported.ModuleName)
paramsKeeper.Subspace(icacontrollertypes.SubModuleName)
paramsKeeper.Subspace(icahosttypes.SubModuleName)
return paramsKeeper
}
// IBC TestingApp functions
// GetBaseApp implements the TestingApp interface.
func (app *SimApp) GetBaseApp() *baseapp.BaseApp {
return app.BaseApp
}
// GetIBCKeeper implements the TestingApp interface.
func (app *SimApp) GetIBCKeeper() *ibckeeper.Keeper {
return app.IBCKeeper
}
// GetTxConfig implements the TestingApp interface.
func (app *SimApp) GetTxConfig() client.TxConfig {
return app.txConfig
}
// GetMemKey returns the MemStoreKey for the provided mem key.
//
// NOTE: This is solely used for testing purposes.
func (app *SimApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
return app.memKeys[storeKey]
}