laconicd/app/app.go
2022-04-22 18:25:14 +05:30

831 lines
31 KiB
Go

package app
import (
"encoding/json"
"io"
"net/http"
"os"
"path/filepath"
"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
"github.com/spf13/cast"
"github.com/tharsis/ethermint/app/middleware"
evmtypes "github.com/tharsis/ethermint/x/evm/types"
"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/codec"
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/db"
"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/simapp"
govv1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
"github.com/cosmos/cosmos-sdk/store/streaming"
"github.com/cosmos/cosmos-sdk/store/v2alpha1/multi"
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"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
authmiddleware "github.com/cosmos/cosmos-sdk/x/auth/middleware"
authsims "github.com/cosmos/cosmos-sdk/x/auth/simulation"
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/authz"
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"
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"
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
"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"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/libs/log"
tmos "github.com/tendermint/tendermint/libs/os"
// "github.com/cosmos/ibc-go/v3/modules/apps/transfer"
// "github.com/cosmos/ibc-go/v3/modules/apps/transfer"
// ibctransferkeeper "github.com/cosmos/ibc-go/v3/modules/apps/transfer/keeper"
// ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
// ibc "github.com/cosmos/ibc-go/v3/modules/core"
// ibcclient "github.com/cosmos/ibc-go/v3/modules/core/02-client"
// ibcclientclient "github.com/cosmos/ibc-go/v3/modules/core/02-client/client"
// porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types"
// ibchost "github.com/cosmos/ibc-go/v3/modules/core/24-host"
// ibckeeper "github.com/cosmos/ibc-go/v3/modules/core/keeper"
// unnamed import of statik for swagger UI support
_ "github.com/tharsis/ethermint/client/docs/statik"
// "github.com/tharsis/ethermint/app/ante"
srvflags "github.com/tharsis/ethermint/server/flags"
ethermint "github.com/tharsis/ethermint/types"
"github.com/tharsis/ethermint/x/evm"
// evmrest "github.com/tharsis/ethermint/x/evm/client/rest"
storetypes "github.com/cosmos/cosmos-sdk/store/v2alpha1"
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
"github.com/tharsis/ethermint/x/feemarket"
feemarketkeeper "github.com/tharsis/ethermint/x/feemarket/keeper"
feemarkettypes "github.com/tharsis/ethermint/x/feemarket/types"
// Force-load the tracer engines to trigger registration due to Go-Ethereum v1.10.15 changes
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
)
func init() {
userHomeDir, err := os.UserHomeDir()
if err != nil {
panic(err)
}
DefaultNodeHome = filepath.Join(userHomeDir, ".ethermintd")
}
const appName = "ethermintd"
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(
[]govclient.ProposalHandler{paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.LegacyProposalHandler, upgradeclient.LegacyCancelProposalHandler},
// ibcclientclient.UpdateClientProposalHandler, ibcclientclient.UpgradeProposalHandler,
),
params.AppModuleBasic{},
crisis.AppModuleBasic{},
slashing.AppModuleBasic{},
// ibc.AppModuleBasic{},
authzmodule.AppModuleBasic{},
feegrantmodule.AppModuleBasic{},
upgrade.AppModuleBasic{},
evidence.AppModuleBasic{},
// transfer.AppModuleBasic{},
vesting.AppModuleBasic{},
// Ethermint modules
evm.AppModuleBasic{},
feemarket.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},
evmtypes.ModuleName: {authtypes.Minter, authtypes.Burner}, // used for secure addition and subtraction of balance using module account
}
// module accounts that are allowed to receive tokens
allowedReceivingModAcc = map[string]bool{
distrtypes.ModuleName: true,
}
)
var _ simapp.App = (*EthermintApp)(nil)
// var _ server.Application (*EthermintApp)(nil)
// EthermintApp implements an extended ABCI application. It is an application
// that may process transactions through Ethereum's EVM running atop of
// Tendermint consensus.
type EthermintApp struct {
*baseapp.BaseApp
// encoding
cdc *codec.LegacyAmino
appCodec codec.Codec
interfaceRegistry types.InterfaceRegistry
msgSvcRouter *authmiddleware.MsgServiceRouter
legacyRouter sdk.Router
invCheckPeriod uint
// 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
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
FeeGrantKeeper feegrantkeeper.Keeper
AuthzKeeper authzkeeper.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
// make scoped keepers public for test purposes
ScopedIBCKeeper capabilitykeeper.ScopedKeeper
ScopedTransferKeeper capabilitykeeper.ScopedKeeper
// Ethermint keepers
EvmKeeper *evmkeeper.Keeper
FeeMarketKeeper feemarketkeeper.Keeper
// the module manager
mm *module.Manager
// simulation manager
sm *module.SimulationManager
// the configurator
configurator module.Configurator
}
// NewEthermintApp returns a reference to a new initialized Ethermint application.
func NewEthermintApp(
logger log.Logger,
db db.DBConnection,
traceStore io.Writer,
loadLatest bool,
skipUpgradeHeights map[int64]bool,
homePath string,
invCheckPeriod uint,
encodingConfig simappparams.EncodingConfig,
appOpts servertypes.AppOptions,
baseAppOptions ...baseapp.AppOption,
) *EthermintApp {
appCodec := encodingConfig.Codec
cdc := encodingConfig.Amino
interfaceRegistry := encodingConfig.InterfaceRegistry
keys := sdk.NewKVStoreKeys(
// SDK keys
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, capabilitytypes.StoreKey,
authzkeeper.StoreKey,
// ibc keys
// ibchost.StoreKey, ibctransfertypes.StoreKey,
// ethermint keys
evmtypes.StoreKey, feemarkettypes.StoreKey,
)
// Add the EVM transient store key
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
// initialize stores
setNamespaces := func(config *multi.StoreParams, ver uint64) error {
for _, key := range keys {
typ, err := storetypes.StoreKeyToType(key)
if err != nil {
return err
}
if err = config.RegisterSubstore(key, typ); err != nil {
return err
}
}
for _, key := range memKeys {
typ, err := storetypes.StoreKeyToType(key)
if err != nil {
return err
}
if err = config.RegisterSubstore(key, typ); err != nil {
return err
}
}
for _, key := range tkeys {
typ, err := storetypes.StoreKeyToType(key)
if err != nil {
return err
}
if err = config.RegisterSubstore(key, typ); err != nil {
return err
}
}
return nil
}
baseAppOptions = append(baseAppOptions, baseapp.StoreOption(setNamespaces))
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
bApp := baseapp.NewBaseApp(
appName,
logger,
db,
baseAppOptions...,
)
bApp.SetCommitMultiStoreTracer(traceStore)
bApp.SetVersion(version.Version)
bApp.SetInterfaceRegistry(interfaceRegistry)
// configure state listening capabilities using AppOptions
// we are doing nothing with the returned streamingServices and waitGroup in this case
if _, _, err := streaming.LoadStreamingServices(bApp, appOpts, appCodec, keys); err != nil {
tmos.Exit(err.Error())
}
app := &EthermintApp{
BaseApp: bApp,
cdc: cdc,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
legacyRouter: authmiddleware.NewLegacyRouter(),
msgSvcRouter: authmiddleware.NewMsgServiceRouter(interfaceRegistry),
keys: keys,
tkeys: tkeys,
memKeys: memKeys,
}
// init params keeper and subspaces
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(paramstypes.ConsensusParamsKeyTable()))
// add capability keeper and ScopeToModule for ibc module
app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
// scopedIBCKeeper := app.CapabilityKeeper.ScopeToModule(ibchost.ModuleName)
// scopedTransferKeeper := app.CapabilityKeeper.ScopeToModule(ibctransfertypes.ModuleName)
// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
// their scoped modules in `NewApp` with `ScopeToModule`
app.CapabilityKeeper.Seal()
// use custom Ethermint account for contracts
app.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), ethermint.ProtoAccount, maccPerms, sdk.Bech32MainPrefix,
)
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.BlockedAddrs(),
)
stakingKeeper := stakingkeeper.NewKeeper(
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, 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.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, 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 = *stakingKeeper.SetHooks(
stakingtypes.NewMultiStakingHooks(app.DistrKeeper.Hooks(), app.SlashingKeeper.Hooks()),
)
app.AuthzKeeper = authzkeeper.NewKeeper(keys[authzkeeper.StoreKey], appCodec, app.msgSvcRouter, app.AccountKeeper)
tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))
// Create Ethermint keepers
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
appCodec, keys[feemarkettypes.StoreKey], app.GetSubspace(feemarkettypes.ModuleName),
)
app.EvmKeeper = evmkeeper.NewKeeper(
appCodec, keys[evmtypes.StoreKey], tkeys[evmtypes.TransientKey], app.GetSubspace(evmtypes.ModuleName),
app.AccountKeeper, app.BankKeeper, app.StakingKeeper, app.FeeMarketKeeper,
tracer,
)
// // Create IBC Keeper
// app.IBCKeeper = ibckeeper.NewKeeper(
// appCodec, keys[ibchost.StoreKey], app.GetSubspace(ibchost.ModuleName), app.StakingKeeper, app.UpgradeKeeper, scopedIBCKeeper,
// )
// register the proposal types
govRouter := govv1beta1.NewRouter()
govRouter.AddRoute(govtypes.RouterKey, govv1beta1.ProposalHandler).
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper))
govConfig := govtypes.DefaultConfig()
/*
Example of setting gov params:
govConfig.MaxMetadataLen = 10000
*/
govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter, app.msgSvcRouter, govConfig,
)
app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(
// register the governance hooks
),
)
// // Create Transfer Keepers
// app.TransferKeeper = ibctransferkeeper.NewKeeper(
// appCodec, keys[ibctransfertypes.StoreKey], app.GetSubspace(ibctransfertypes.ModuleName),
// app.IBCKeeper.ChannelKeeper, app.IBCKeeper.ChannelKeeper, &app.IBCKeeper.PortKeeper,
// app.AccountKeeper, app.BankKeeper, scopedTransferKeeper,
// )
// transferModule := transfer.NewAppModule(app.TransferKeeper)
// transferIBCModule := transfer.NewIBCModule(app.TransferKeeper)
// Create static IBC router, add transfer route, then set and seal it
// ibcRouter := porttypes.NewRouter()
// ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferIBCModule)
// app.IBCKeeper.SetRouter(ibcRouter)
// create evidence keeper with router
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
/**** 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.
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(
// SDK app modules
genutil.NewAppModule(
app.AccountKeeper, app.StakingKeeper, app.BaseApp.DeliverTx,
encodingConfig.TxConfig,
),
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
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),
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
params.NewAppModule(app.ParamsKeeper),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
// ibc modules
// ibc.NewAppModule(app.IBCKeeper),
// Ethermint app modules
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
feemarket.NewAppModule(app.FeeMarketKeeper),
)
// 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: upgrade module must go first to handle software upgrades.
// NOTE: staking module is required if HistoricalEntries param > 0.
// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)
app.mm.SetOrderBeginBlockers(
upgradetypes.ModuleName,
capabilitytypes.ModuleName,
feemarkettypes.ModuleName,
evmtypes.ModuleName,
minttypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
evidencetypes.ModuleName,
stakingtypes.ModuleName,
// no-op modules
authtypes.ModuleName,
banktypes.ModuleName,
govtypes.ModuleName,
crisistypes.ModuleName,
genutiltypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
vestingtypes.ModuleName,
)
// NOTE: fee market module must go last in order to retrieve the block gas used.
app.mm.SetOrderEndBlockers(
crisistypes.ModuleName,
govtypes.ModuleName,
stakingtypes.ModuleName,
evmtypes.ModuleName,
feemarkettypes.ModuleName,
// no-op modules
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
slashingtypes.ModuleName,
minttypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.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.
app.mm.SetOrderInitGenesis(
// SDK modules
capabilitytypes.ModuleName,
authtypes.ModuleName,
banktypes.ModuleName,
distrtypes.ModuleName,
stakingtypes.ModuleName,
slashingtypes.ModuleName,
govtypes.ModuleName,
minttypes.ModuleName,
genutiltypes.ModuleName,
evidencetypes.ModuleName,
authz.ModuleName,
feegrant.ModuleName,
paramstypes.ModuleName,
upgradetypes.ModuleName,
vestingtypes.ModuleName,
// Ethermint modules
evmtypes.ModuleName,
feemarkettypes.ModuleName,
// NOTE: crisis module must go at the end to check for invariants on each module
crisistypes.ModuleName,
)
app.mm.RegisterInvariants(&app.CrisisKeeper)
app.mm.RegisterRoutes(app.legacyRouter, app.QueryRouter(), encodingConfig.Amino)
app.configurator = module.NewConfigurator(app.appCodec, app.msgSvcRouter, app.GRPCQueryRouter())
app.mm.RegisterServices(app.configurator)
// add test gRPC service for testing gRPC queries in isolation
// testdata.RegisterTestServiceServer(app.GRPCQueryRouter(), testdata.TestServiceImpl{})
// 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
app.sm = module.NewSimulationManager(
auth.NewAppModule(appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
bank.NewAppModule(appCodec, app.BankKeeper, app.AccountKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
params.NewAppModule(app.ParamsKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
// ibc.NewAppModule(app.IBCKeeper),
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
feemarket.NewAppModule(app.FeeMarketKeeper),
)
app.sm.RegisterStoreDecoders()
// initialize BaseApp
app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
// app.ScopedIBCKeeper = scopedIBCKeeper
// app.ScopedTransferKeeper = scopedTransferKeeper
maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
options := middleware.HandlerOptions{
Debug: app.Trace(),
LegacyRouter: app.legacyRouter,
MsgServiceRouter: app.msgSvcRouter,
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
EvmKeeper: app.EvmKeeper,
FeegrantKeeper: app.FeeGrantKeeper,
FeeMarketKeeper: app.FeeMarketKeeper,
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: middleware.DefaultSigVerificationGasConsumer,
MaxTxGasWanted: maxGasWanted,
TxDecoder: encodingConfig.TxConfig.TxDecoder(),
}
app.setTxHandler(options, encodingConfig.TxConfig, cast.ToStringSlice(appOpts.Get(server.FlagIndexEvents)))
return app
}
func (app *EthermintApp) setTxHandler(options middleware.HandlerOptions, txConfig client.TxConfig, indexEventsStr []string) {
indexEvents := map[string]struct{}{}
for _, e := range indexEventsStr {
indexEvents[e] = struct{}{}
}
txHandler, err := middleware.NewMiddleware(indexEventsStr, options)
if err != nil {
panic(err)
}
app.SetTxHandler(txHandler)
}
// Name returns the name of the App
func (app *EthermintApp) Name() string { return app.BaseApp.Name() }
// BeginBlocker updates every begin block
func (app *EthermintApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock {
return app.mm.BeginBlock(ctx, req)
}
// EndBlocker updates every end block
func (app *EthermintApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
return app.mm.EndBlock(ctx, req)
}
// InitChainer updates at chain initialization
func (app *EthermintApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
var genesisState simapp.GenesisState
if err := json.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 state at a particular height
func (app *EthermintApp) LoadHeight(height int64) error {
// return app.LoadVersion(height)
return nil
}
// ModuleAccountAddrs returns all the app's module account addresses.
func (app *EthermintApp) ModuleAccountAddrs() map[string]bool {
modAccAddrs := make(map[string]bool)
for acc := range maccPerms {
modAccAddrs[authtypes.NewModuleAddress(acc).String()] = true
}
return modAccAddrs
}
// BlockedAddrs returns all the app's module account addresses that are not
// allowed to receive external tokens.
func (app *EthermintApp) BlockedAddrs() map[string]bool {
blockedAddrs := make(map[string]bool)
for acc := range maccPerms {
blockedAddrs[authtypes.NewModuleAddress(acc).String()] = !allowedReceivingModAcc[acc]
}
return blockedAddrs
}
// LegacyAmino returns EthermintApp'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 *EthermintApp) LegacyAmino() *codec.LegacyAmino {
return app.cdc
}
// AppCodec returns EthermintApp'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 *EthermintApp) AppCodec() codec.Codec {
return app.appCodec
}
// InterfaceRegistry returns EthermintApp's InterfaceRegistry
func (app *EthermintApp) 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 *EthermintApp) GetKey(storeKey string) *storetypes.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 *EthermintApp) GetTKey(storeKey string) *storetypes.TransientStoreKey {
return app.tkeys[storeKey]
}
// GetMemKey returns the MemStoreKey for the provided mem key.
//
// NOTE: This is solely used for testing purposes.
func (app *EthermintApp) GetMemKey(storeKey string) *storetypes.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 *EthermintApp) GetSubspace(moduleName string) paramstypes.Subspace {
subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
return subspace
}
// SimulationManager implements the SimulationApp interface
func (app *EthermintApp) SimulationManager() *module.SimulationManager {
return app.sm
}
// RegisterAPIRoutes registers all application module routes with the provided
// API server.
func (app *EthermintApp) RegisterAPIRoutes(apiSvr *api.Server, apiConfig config.APIConfig) {
clientCtx := apiSvr.ClientCtx
// rpc.RegisterRoutes(clientCtx, apiSvr.Router)
// evmrest.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 swagger API from root so that other applications can override easily
if apiConfig.Swagger {
RegisterSwaggerAPI(clientCtx, apiSvr.Router)
}
}
func (app *EthermintApp) RegisterTxService(clientCtx client.Context) {
authtx.RegisterTxService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.BaseApp.Simulate, app.interfaceRegistry)
}
func (app *EthermintApp) RegisterTendermintService(clientCtx client.Context) {
tmservice.RegisterTendermintService(app.BaseApp.GRPCQueryRouter(), clientCtx, app.interfaceRegistry)
}
// RegisterSwaggerAPI registers swagger route with API Server
func RegisterSwaggerAPI(_ client.Context, rtr *mux.Router) {
statikFS, err := fs.New()
if err != nil {
panic(err)
}
staticServer := http.FileServer(statikFS)
rtr.PathPrefix("/swagger/").Handler(http.StripPrefix("/swagger/", staticServer))
}
// 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 storetypes.StoreKey,
) paramskeeper.Keeper {
paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey)
// SDK subspaces
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(govv1.ParamKeyTable())
paramsKeeper.Subspace(crisistypes.ModuleName)
// paramsKeeper.Subspace(ibctransfertypes.ModuleName)
// paramsKeeper.Subspace(ibchost.ModuleName)
// ethermint subspaces
paramsKeeper.Subspace(evmtypes.ModuleName)
paramsKeeper.Subspace(feemarkettypes.ModuleName)
return paramsKeeper
}