github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/simapp/app.go (about)

     1  package simapp
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  
     7  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/mpt"
     8  
     9  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    10  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    11  	tmos "github.com/fibonacci-chain/fbc/libs/tendermint/libs/os"
    12  	dbm "github.com/fibonacci-chain/fbc/libs/tm-db"
    13  
    14  	bam "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    15  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    16  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/module"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    19  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/ante"
    21  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/vesting"
    22  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/bank"
    23  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/crisis"
    24  	distr "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/distribution"
    25  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/evidence"
    26  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/genutil"
    27  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov"
    28  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/mint"
    29  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/params"
    30  	paramsclient "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/params/client"
    31  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/slashing"
    32  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking"
    33  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/supply"
    34  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade"
    35  	upgradeclient "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/upgrade/client"
    36  )
    37  
    38  const appName = "SimApp"
    39  
    40  var (
    41  	// DefaultCLIHome default home directories for the application CLI
    42  	DefaultCLIHome = os.ExpandEnv("$HOME/.simapp")
    43  
    44  	// DefaultNodeHome default home directories for the application daemon
    45  	DefaultNodeHome = os.ExpandEnv("$HOME/.simapp")
    46  
    47  	// ModuleBasics defines the module BasicManager is in charge of setting up basic,
    48  	// non-dependant module elements, such as codec registration
    49  	// and genesis verification.
    50  	ModuleBasics = module.NewBasicManager(
    51  		auth.AppModuleBasic{},
    52  		supply.AppModuleBasic{},
    53  		genutil.AppModuleBasic{},
    54  		bank.AppModuleBasic{},
    55  		staking.AppModuleBasic{},
    56  		mint.AppModuleBasic{},
    57  		distr.AppModuleBasic{},
    58  		gov.NewAppModuleBasic(
    59  			paramsclient.ProposalHandler, distr.ProposalHandler, upgradeclient.ProposalHandler,
    60  		),
    61  		params.AppModuleBasic{},
    62  		crisis.AppModuleBasic{},
    63  		slashing.AppModuleBasic{},
    64  		upgrade.AppModuleBasic{},
    65  		evidence.AppModuleBasic{},
    66  	)
    67  
    68  	// module account permissions
    69  	maccPerms = map[string][]string{
    70  		auth.FeeCollectorName:     nil,
    71  		distr.ModuleName:          nil,
    72  		mint.ModuleName:           {supply.Minter},
    73  		staking.BondedPoolName:    {supply.Burner, supply.Staking},
    74  		staking.NotBondedPoolName: {supply.Burner, supply.Staking},
    75  		gov.ModuleName:            {supply.Burner},
    76  		supply.ModuleName:         nil,
    77  	}
    78  
    79  	// module accounts that are allowed to receive tokens
    80  	allowedReceivingModAcc = map[string]bool{
    81  		distr.ModuleName: true,
    82  	}
    83  )
    84  
    85  // MakeCodec - custom tx codec
    86  func MakeCodec() *codec.Codec {
    87  	var cdc = codec.New()
    88  	ModuleBasics.RegisterCodec(cdc)
    89  	vesting.RegisterCodec(cdc)
    90  	sdk.RegisterCodec(cdc)
    91  	codec.RegisterCrypto(cdc)
    92  	return cdc
    93  }
    94  
    95  // Verify app interface at compile time
    96  var _ App = (*SimApp)(nil)
    97  
    98  // SimApp extends an ABCI application, but with most of its parameters exported.
    99  // They are exported for convenience in creating helper functions, as object
   100  // capabilities aren't needed for testing.
   101  type SimApp struct {
   102  	*bam.BaseApp
   103  	cdc *codec.Codec
   104  
   105  	invCheckPeriod uint
   106  
   107  	// keys to access the substores
   108  	keys  map[string]*sdk.KVStoreKey
   109  	tkeys map[string]*sdk.TransientStoreKey
   110  
   111  	// subspaces
   112  	subspaces map[string]params.Subspace
   113  
   114  	// keepers
   115  	AccountKeeper  auth.AccountKeeper
   116  	BankKeeper     bank.Keeper
   117  	SupplyKeeper   supply.Keeper
   118  	StakingKeeper  staking.Keeper
   119  	SlashingKeeper slashing.Keeper
   120  	MintKeeper     mint.Keeper
   121  	DistrKeeper    distr.Keeper
   122  	GovKeeper      gov.Keeper
   123  	CrisisKeeper   crisis.Keeper
   124  	UpgradeKeeper  upgrade.Keeper
   125  	ParamsKeeper   params.Keeper
   126  	EvidenceKeeper evidence.Keeper
   127  
   128  	// the module manager
   129  	mm *module.Manager
   130  
   131  	// simulation manager
   132  	sm *module.SimulationManager
   133  }
   134  
   135  // NewSimApp returns a reference to an initialized SimApp.
   136  func NewSimApp(
   137  	logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool,
   138  	invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp),
   139  ) *SimApp {
   140  
   141  	cdc := MakeCodec()
   142  
   143  	bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...)
   144  	bApp.SetCommitMultiStoreTracer(traceStore)
   145  	bApp.SetAppVersion(version.Version)
   146  
   147  	keys := sdk.NewKVStoreKeys(
   148  		bam.MainStoreKey, auth.StoreKey, staking.StoreKey,
   149  		supply.StoreKey, mint.StoreKey, distr.StoreKey, slashing.StoreKey,
   150  		gov.StoreKey, params.StoreKey, upgrade.StoreKey, evidence.StoreKey, mpt.StoreKey,
   151  	)
   152  	tkeys := sdk.NewTransientStoreKeys(params.TStoreKey)
   153  
   154  	app := &SimApp{
   155  		BaseApp:        bApp,
   156  		cdc:            cdc,
   157  		invCheckPeriod: invCheckPeriod,
   158  		keys:           keys,
   159  		tkeys:          tkeys,
   160  		subspaces:      make(map[string]params.Subspace),
   161  	}
   162  
   163  	// init params keeper and subspaces
   164  	app.ParamsKeeper = params.NewKeeper(app.cdc, keys[params.StoreKey], tkeys[params.TStoreKey])
   165  	app.subspaces[auth.ModuleName] = app.ParamsKeeper.Subspace(auth.DefaultParamspace)
   166  	app.subspaces[bank.ModuleName] = app.ParamsKeeper.Subspace(bank.DefaultParamspace)
   167  	app.subspaces[staking.ModuleName] = app.ParamsKeeper.Subspace(staking.DefaultParamspace)
   168  	app.subspaces[mint.ModuleName] = app.ParamsKeeper.Subspace(mint.DefaultParamspace)
   169  	app.subspaces[distr.ModuleName] = app.ParamsKeeper.Subspace(distr.DefaultParamspace)
   170  	app.subspaces[slashing.ModuleName] = app.ParamsKeeper.Subspace(slashing.DefaultParamspace)
   171  	app.subspaces[gov.ModuleName] = app.ParamsKeeper.Subspace(gov.DefaultParamspace).WithKeyTable(gov.ParamKeyTable())
   172  	app.subspaces[crisis.ModuleName] = app.ParamsKeeper.Subspace(crisis.DefaultParamspace)
   173  	app.subspaces[evidence.ModuleName] = app.ParamsKeeper.Subspace(evidence.DefaultParamspace)
   174  
   175  	// add keepers
   176  	app.AccountKeeper = auth.NewAccountKeeper(
   177  		app.cdc, keys[auth.StoreKey], keys[mpt.StoreKey], app.subspaces[auth.ModuleName], auth.ProtoBaseAccount,
   178  	)
   179  	app.BankKeeper = bank.NewBaseKeeper(
   180  		app.AccountKeeper, app.subspaces[bank.ModuleName], app.BlacklistedAccAddrs(),
   181  	)
   182  	app.SupplyKeeper = supply.NewKeeper(
   183  		app.cdc, keys[supply.StoreKey], app.AccountKeeper, bank.NewBankKeeperAdapter(app.BankKeeper), maccPerms,
   184  	)
   185  	stakingKeeper := staking.NewKeeper(
   186  		app.cdc, keys[staking.StoreKey], app.SupplyKeeper, app.subspaces[staking.ModuleName],
   187  	)
   188  	app.MintKeeper = mint.NewKeeper(
   189  		app.cdc, keys[mint.StoreKey], app.subspaces[mint.ModuleName], &stakingKeeper,
   190  		app.SupplyKeeper, auth.FeeCollectorName, "",
   191  	)
   192  	app.DistrKeeper = distr.NewKeeper(
   193  		app.cdc, keys[distr.StoreKey], app.subspaces[distr.ModuleName], &stakingKeeper,
   194  		app.SupplyKeeper, auth.FeeCollectorName, app.ModuleAccountAddrs(),
   195  	)
   196  	app.SlashingKeeper = slashing.NewKeeper(
   197  		app.cdc, keys[slashing.StoreKey], &stakingKeeper, app.subspaces[slashing.ModuleName],
   198  	)
   199  	app.CrisisKeeper = crisis.NewKeeper(
   200  		app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName,
   201  	)
   202  	app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], app.cdc)
   203  
   204  	// create evidence keeper with router
   205  	evidenceKeeper := evidence.NewKeeper(
   206  		app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], &app.StakingKeeper, app.SlashingKeeper,
   207  	)
   208  	evidenceRouter := evidence.NewRouter()
   209  	// TODO: Register evidence routes.
   210  	evidenceKeeper.SetRouter(evidenceRouter)
   211  	app.EvidenceKeeper = *evidenceKeeper
   212  
   213  	// register the proposal types
   214  	govRouter := gov.NewRouter()
   215  	govRouter.AddRoute(gov.RouterKey, gov.ProposalHandler).
   216  		AddRoute(params.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
   217  		AddRoute(distr.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
   218  		AddRoute(upgrade.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
   219  	app.GovKeeper = gov.NewKeeper(
   220  		app.cdc, keys[gov.StoreKey], app.subspaces[gov.ModuleName], app.SupplyKeeper,
   221  		&stakingKeeper, govRouter,
   222  	)
   223  
   224  	// register the staking hooks
   225  	// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
   226  	app.StakingKeeper = *stakingKeeper.SetHooks(
   227  		staking.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
   228  	)
   229  
   230  	// NOTE: Any module instantiated in the module manager that is later modified
   231  	// must be passed by reference here.
   232  	app.mm = module.NewManager(
   233  		genutil.NewAppModule(app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx),
   234  		auth.NewAppModule(app.AccountKeeper),
   235  		bank.NewAppModule(app.BankKeeper, app.AccountKeeper, app.SupplyKeeper),
   236  		crisis.NewAppModule(&app.CrisisKeeper),
   237  		supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
   238  		gov.NewAppModule(app.GovKeeper, app.AccountKeeper, app.SupplyKeeper),
   239  		mint.NewAppModule(app.MintKeeper),
   240  		slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
   241  		distr.NewAppModule(app.DistrKeeper, app.AccountKeeper, app.SupplyKeeper, app.StakingKeeper),
   242  		staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
   243  		upgrade.NewAppModule(app.UpgradeKeeper),
   244  		evidence.NewAppModule(app.EvidenceKeeper),
   245  	)
   246  
   247  	// During begin block slashing happens after distr.BeginBlocker so that
   248  	// there is nothing left over in the validator fee pool, so as to keep the
   249  	// CanWithdrawInvariant invariant.
   250  	app.mm.SetOrderBeginBlockers(upgrade.ModuleName, mint.ModuleName, distr.ModuleName, slashing.ModuleName, evidence.ModuleName)
   251  	app.mm.SetOrderEndBlockers(crisis.ModuleName, gov.ModuleName, staking.ModuleName)
   252  
   253  	// NOTE: The genutils moodule must occur after staking so that pools are
   254  	// properly initialized with tokens from genesis accounts.
   255  	app.mm.SetOrderInitGenesis(
   256  		auth.ModuleName, distr.ModuleName, staking.ModuleName, bank.ModuleName,
   257  		slashing.ModuleName, gov.ModuleName, mint.ModuleName, supply.ModuleName,
   258  		crisis.ModuleName, genutil.ModuleName, evidence.ModuleName,
   259  	)
   260  
   261  	app.mm.RegisterInvariants(&app.CrisisKeeper)
   262  	app.mm.RegisterRoutes(app.Router(), app.QueryRouter())
   263  
   264  	// create the simulation manager and define the order of the modules for deterministic simulations
   265  	//
   266  	// NOTE: this is not required apps that don't use the simulator for fuzz testing
   267  	// transactions
   268  	app.sm = module.NewSimulationManager(
   269  		auth.NewAppModule(app.AccountKeeper),
   270  		bank.NewAppModule(app.BankKeeper, app.AccountKeeper, app.SupplyKeeper),
   271  		supply.NewAppModule(app.SupplyKeeper, app.AccountKeeper),
   272  		gov.NewAppModule(app.GovKeeper, app.AccountKeeper, app.SupplyKeeper),
   273  		mint.NewAppModule(app.MintKeeper),
   274  		staking.NewAppModule(app.StakingKeeper, app.AccountKeeper, app.SupplyKeeper),
   275  		distr.NewAppModule(app.DistrKeeper, app.AccountKeeper, app.SupplyKeeper, app.StakingKeeper),
   276  		slashing.NewAppModule(app.SlashingKeeper, app.AccountKeeper, app.StakingKeeper),
   277  		params.NewAppModule(), // NOTE: only used for simulation to generate randomized param change proposals
   278  	)
   279  
   280  	app.sm.RegisterStoreDecoders()
   281  
   282  	// initialize stores
   283  	app.MountKVStores(keys)
   284  	app.MountTransientStores(tkeys)
   285  
   286  	// initialize BaseApp
   287  	app.SetInitChainer(app.InitChainer)
   288  	app.SetBeginBlocker(app.BeginBlocker)
   289  	app.SetAnteHandler(ante.NewAnteHandler(app.AccountKeeper, app.SupplyKeeper, auth.DefaultSigVerificationGasConsumer))
   290  	app.SetEndBlocker(app.EndBlocker)
   291  
   292  	if loadLatest {
   293  		err := app.LoadLatestVersion(app.keys[bam.MainStoreKey])
   294  		if err != nil {
   295  			tmos.Exit(err.Error())
   296  		}
   297  	}
   298  
   299  	return app
   300  }
   301  
   302  // Name returns the name of the App
   303  func (app *SimApp) Name() string { return app.BaseApp.Name() }
   304  
   305  // BeginBlocker application updates every begin block
   306  func (app *SimApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
   307  	return app.mm.BeginBlock(ctx, req)
   308  }
   309  
   310  // EndBlocker application updates every end block
   311  func (app *SimApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
   312  	return app.mm.EndBlock(ctx, req)
   313  }
   314  
   315  // InitChainer application update at chain initialization
   316  func (app *SimApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
   317  	var genesisState GenesisState
   318  	app.cdc.MustUnmarshalJSON(req.AppStateBytes, &genesisState)
   319  	return app.mm.InitGenesis(ctx, genesisState)
   320  }
   321  
   322  // LoadHeight loads a particular height
   323  func (app *SimApp) LoadHeight(height int64) error {
   324  	return app.LoadVersion(height, app.keys[bam.MainStoreKey])
   325  }
   326  
   327  // ModuleAccountAddrs returns all the app's module account addresses.
   328  func (app *SimApp) ModuleAccountAddrs() map[string]bool {
   329  	modAccAddrs := make(map[string]bool)
   330  	for acc := range maccPerms {
   331  		modAccAddrs[supply.NewModuleAddress(acc).String()] = true
   332  	}
   333  
   334  	return modAccAddrs
   335  }
   336  
   337  // BlacklistedAccAddrs returns all the app's module account addresses black listed for receiving tokens.
   338  func (app *SimApp) BlacklistedAccAddrs() map[string]bool {
   339  	blacklistedAddrs := make(map[string]bool)
   340  	for acc := range maccPerms {
   341  		blacklistedAddrs[supply.NewModuleAddress(acc).String()] = !allowedReceivingModAcc[acc]
   342  	}
   343  
   344  	return blacklistedAddrs
   345  }
   346  
   347  // Codec returns SimApp's codec.
   348  //
   349  // NOTE: This is solely to be used for testing purposes as it may be desirable
   350  // for modules to register their own custom testing types.
   351  func (app *SimApp) Codec() *codec.Codec {
   352  	return app.cdc
   353  }
   354  
   355  // GetKey returns the KVStoreKey for the provided store key.
   356  //
   357  // NOTE: This is solely to be used for testing purposes.
   358  func (app *SimApp) GetKey(storeKey string) *sdk.KVStoreKey {
   359  	return app.keys[storeKey]
   360  }
   361  
   362  // GetTKey returns the TransientStoreKey for the provided store key.
   363  //
   364  // NOTE: This is solely to be used for testing purposes.
   365  func (app *SimApp) GetTKey(storeKey string) *sdk.TransientStoreKey {
   366  	return app.tkeys[storeKey]
   367  }
   368  
   369  // GetSubspace returns a param subspace for a given module name.
   370  //
   371  // NOTE: This is solely to be used for testing purposes.
   372  func (app *SimApp) GetSubspace(moduleName string) params.Subspace {
   373  	return app.subspaces[moduleName]
   374  }
   375  
   376  // SimulationManager implements the SimulationApp interface
   377  func (app *SimApp) SimulationManager() *module.SimulationManager {
   378  	return app.sm
   379  }
   380  
   381  // GetMaccPerms returns a copy of the module account permissions
   382  func GetMaccPerms() map[string][]string {
   383  	dupMaccPerms := make(map[string][]string)
   384  	for k, v := range maccPerms {
   385  		dupMaccPerms[k] = v
   386  	}
   387  	return dupMaccPerms
   388  }