/go:build !app_v1
package simapp
import (
_ "embed"
"io"
"os"
"path/filepath"
"github.com/tendermint/tendermint/libs/log"
dbm "github.com/tendermint/tm-db"
"cosmossdk.io/depinject"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/runtime"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/cosmos/cosmos-sdk/store/streaming"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/testutil/testdata_pulsar"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/x/auth"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" / import for side-effects
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
authzmodule "github.com/cosmos/cosmos-sdk/x/authz/module"
"github.com/cosmos/cosmos-sdk/x/bank"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
"github.com/cosmos/cosmos-sdk/x/capability"
capabilitykeeper "github.com/cosmos/cosmos-sdk/x/capability/keeper"
consensus "github.com/cosmos/cosmos-sdk/x/consensus"
consensuskeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
"github.com/cosmos/cosmos-sdk/x/crisis"
crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper"
distr "github.com/cosmos/cosmos-sdk/x/distribution"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
"github.com/cosmos/cosmos-sdk/x/evidence"
evidencekeeper "github.com/cosmos/cosmos-sdk/x/evidence/keeper"
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"
groupkeeper "github.com/cosmos/cosmos-sdk/x/group/keeper"
groupmodule "github.com/cosmos/cosmos-sdk/x/group/module"
"github.com/cosmos/cosmos-sdk/x/mint"
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
nftkeeper "github.com/cosmos/cosmos-sdk/x/nft/keeper"
nftmodule "github.com/cosmos/cosmos-sdk/x/nft/module"
"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"
"github.com/cosmos/cosmos-sdk/x/slashing"
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"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"
)
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.NewAppModuleBasic(genutiltypes.DefaultMessageValidator),
bank.AppModuleBasic{
},
capability.AppModuleBasic{
},
staking.AppModuleBasic{
},
mint.AppModuleBasic{
},
distr.AppModuleBasic{
},
gov.NewAppModuleBasic(
[]govclient.ProposalHandler{
paramsclient.ProposalHandler,
upgradeclient.LegacyProposalHandler,
upgradeclient.LegacyCancelProposalHandler,
},
),
params.AppModuleBasic{
},
crisis.AppModuleBasic{
},
slashing.AppModuleBasic{
},
feegrantmodule.AppModuleBasic{
},
upgrade.AppModuleBasic{
},
evidence.AppModuleBasic{
},
authzmodule.AppModuleBasic{
},
groupmodule.AppModuleBasic{
},
vesting.AppModuleBasic{
},
nftmodule.AppModuleBasic{
},
consensus.AppModuleBasic{
},
)
)
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, as object
/ capabilities aren't needed for testing.
type SimApp struct {
*runtime.App
legacyAmino *codec.LegacyAmino
appCodec codec.Codec
txConfig client.TxConfig
interfaceRegistry codectypes.InterfaceRegistry
/ 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
AuthzKeeper authzkeeper.Keeper
EvidenceKeeper evidencekeeper.Keeper
FeeGrantKeeper feegrantkeeper.Keeper
GroupKeeper groupkeeper.Keeper
NFTKeeper nftkeeper.Keeper
ConsensusParamsKeeper consensuskeeper.Keeper
/ simulation manager
sm *module.SimulationManager
}
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 {
var (
app = &SimApp{
}
appBuilder *runtime.AppBuilder
/ Below we could construct and set an application specific mempool and ABCI 1.0 Prepare and Process Proposal
/ handlers. These defaults are already set in the SDK's BaseApp, this shows an example of how to override
/ them.
/
/ nonceMempool = mempool.NewSenderNonceMempool()
/ mempoolOpt = baseapp.SetMempool(nonceMempool)
/ prepareOpt = func(app *baseapp.BaseApp) {
/ app.SetPrepareProposal(app.DefaultPrepareProposal())
/
}
/ processOpt = func(app *baseapp.BaseApp) {
/ app.SetProcessProposal(app.DefaultProcessProposal())
/
}
/
/ Further down we'd set the options in the AppBuilder like below.
/ baseAppOptions = append(baseAppOptions, mempoolOpt, prepareOpt, processOpt)
/ merge the AppConfig and other configuration in one config
appConfig = depinject.Configs(
AppConfig,
depinject.Supply(
/ supply the application options
appOpts,
/ ADVANCED CONFIGURATION
/
/ AUTH
/
/ For providing a custom function required in auth to generate custom account types
/ add it below. By default the auth module uses simulation.RandomGenesisAccounts.
/
/ authtypes.RandomGenesisAccountsFn(simulation.RandomGenesisAccounts),
/ For providing a custom a base account type add it below.
/ By default the auth module uses authtypes.ProtoBaseAccount().
/
/ func()
authtypes.AccountI {
return authtypes.ProtoBaseAccount()
},
/
/ MINT
/
/ For providing a custom inflation function for x/mint add here your
/ custom function that implements the minttypes.InflationCalculationFn
/ interface.
),
)
)
if err := depinject.Inject(appConfig,
&appBuilder,
&app.appCodec,
&app.legacyAmino,
&app.txConfig,
&app.interfaceRegistry,
&app.AccountKeeper,
&app.BankKeeper,
&app.CapabilityKeeper,
&app.StakingKeeper,
&app.SlashingKeeper,
&app.MintKeeper,
&app.DistrKeeper,
&app.GovKeeper,
&app.CrisisKeeper,
&app.UpgradeKeeper,
&app.ParamsKeeper,
&app.AuthzKeeper,
&app.EvidenceKeeper,
&app.FeeGrantKeeper,
&app.GroupKeeper,
&app.NFTKeeper,
&app.ConsensusParamsKeeper,
); err != nil {
panic(err)
}
app.App = appBuilder.Build(logger, db, traceStore, baseAppOptions...)
/ load state streaming if enabled
if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, logger, app.kvStoreKeys()); err != nil {
logger.Error("failed to load state streaming", "err", err)
os.Exit(1)
}
/**** Module Options ****/
app.ModuleManager.RegisterInvariants(app.CrisisKeeper)
/ RegisterUpgradeHandlers is used for registering any on-chain upgrades.
app.RegisterUpgradeHandlers()
/ add test gRPC service for testing gRPC queries in isolation
testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.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.sm = module.NewSimulationManagerFromAppModules(app.ModuleManager.Modules, overrideModules)
app.sm.RegisterStoreDecoders()
/ A custom InitChainer can be set if extra pre-init-genesis logic is required.
/ By default, when using app wiring enabled module, this is not required.
/ For instance, the upgrade module will set automatically the module version map in its init genesis thanks to app wiring.
/ However, when registering a module manually (i.e. that does not support app wiring), the module version map
/ must be set manually as follow. The upgrade module will de-duplicate the module version map.
/
/ app.SetInitChainer(func(ctx sdk.Context, req abci.RequestInitChain)
abci.ResponseInitChain {
/ app.UpgradeKeeper.SetModuleVersionMap(ctx, app.ModuleManager.GetVersionMap())
/ return app.App.InitChainer(ctx, req)
/
})
if err := app.Load(loadLatest); err != nil {
panic(err)
}
return app
}
/ Name returns the name of the App
func (app *SimApp)
Name()
string {
return app.BaseApp.Name()
}
/ 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()
codectypes.InterfaceRegistry {
return app.interfaceRegistry
}
/ TxConfig returns SimApp's TxConfig
func (app *SimApp)
TxConfig()
client.TxConfig {
return app.txConfig
}
/ 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 {
sk := app.UnsafeFindStoreKey(storeKey)
kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
if !ok {
return nil
}
return kvStoreKey
}
func (app *SimApp)
kvStoreKeys()
map[string]*storetypes.KVStoreKey {
keys := make(map[string]*storetypes.KVStoreKey)
for _, k := range app.GetStoreKeys() {
if kv, ok := k.(*storetypes.KVStoreKey); ok {
keys[kv.Name()] = kv
}
}
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.sm
}
/ RegisterAPIRoutes registers all application module routes with the provided
/ API server.
func (app *SimApp)
RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
app.App.RegisterAPIRoutes(apiSvr, apiConfig)
/ register swagger API in app.go so that other applications can override easily
if err := server.RegisterSwaggerAPI(apiSvr.ClientCtx, apiSvr.Router, apiConfig.Swagger); err != nil {
panic(err)
}
}
/ GetMaccPerms returns a copy of the module account permissions
/
/ NOTE: This is solely to be used for testing purposes.
func GetMaccPerms()
map[string][]string {
dup := make(map[string][]string)
for _, perms := range moduleAccPerms {
dup[perms.Account] = perms.Permissions
}
return dup
}
/ BlockedAddresses returns all the app's blocked account addresses.
func BlockedAddresses()
map[string]bool {
result := make(map[string]bool)
if len(blockAccAddrs) > 0 {
for _, addr := range blockAccAddrs {
result[addr] = true
}
}
else {
for addr := range GetMaccPerms() {
result[addr] = true
}
}
return result
}