e90b21bc8e
1. add bond,auction, nameserivce module 2. update to v0.12.2 ethermint version 3. fix the test cases 4. add gql server
852 lines
32 KiB
Go
852 lines
32 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"
|
|
|
|
abci "github.com/tendermint/tendermint/abci/types"
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
tmos "github.com/tendermint/tendermint/libs/os"
|
|
dbm "github.com/tendermint/tm-db"
|
|
|
|
"github.com/cosmos/cosmos-sdk/baseapp"
|
|
"github.com/cosmos/cosmos-sdk/client"
|
|
"github.com/cosmos/cosmos-sdk/client/grpc/tmservice"
|
|
"github.com/cosmos/cosmos-sdk/client/rpc"
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
"github.com/cosmos/cosmos-sdk/codec/types"
|
|
"github.com/cosmos/cosmos-sdk/server/api"
|
|
"github.com/cosmos/cosmos-sdk/server/config"
|
|
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
|
"github.com/cosmos/cosmos-sdk/simapp"
|
|
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
|
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"
|
|
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"
|
|
govkeeper "github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
|
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
|
"github.com/cosmos/cosmos-sdk/x/mint"
|
|
mintkeeper "github.com/cosmos/cosmos-sdk/x/mint/keeper"
|
|
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
|
"github.com/cosmos/cosmos-sdk/x/params"
|
|
paramsclient "github.com/cosmos/cosmos-sdk/x/params/client"
|
|
paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper"
|
|
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
|
paramproposal "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
|
"github.com/cosmos/cosmos-sdk/x/slashing"
|
|
slashingkeeper "github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
|
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
|
"github.com/cosmos/cosmos-sdk/x/staking"
|
|
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
|
|
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
|
"github.com/cosmos/cosmos-sdk/x/upgrade"
|
|
upgradeclient "github.com/cosmos/cosmos-sdk/x/upgrade/client"
|
|
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
|
|
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
|
|
|
"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"
|
|
evmkeeper "github.com/tharsis/ethermint/x/evm/keeper"
|
|
evmtypes "github.com/tharsis/ethermint/x/evm/types"
|
|
"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"
|
|
|
|
"github.com/tharsis/ethermint/x/auction"
|
|
auctionkeeper "github.com/tharsis/ethermint/x/auction/keeper"
|
|
auctiontypes "github.com/tharsis/ethermint/x/auction/types"
|
|
"github.com/tharsis/ethermint/x/bond"
|
|
bondkeeper "github.com/tharsis/ethermint/x/bond/keeper"
|
|
bondtypes "github.com/tharsis/ethermint/x/bond/types"
|
|
"github.com/tharsis/ethermint/x/nameservice"
|
|
nameservicekeeper "github.com/tharsis/ethermint/x/nameservice/keeper"
|
|
nameservicetypes "github.com/tharsis/ethermint/x/nameservice/types"
|
|
)
|
|
|
|
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(
|
|
paramsclient.ProposalHandler, distrclient.ProposalHandler, upgradeclient.ProposalHandler, upgradeclient.CancelProposalHandler,
|
|
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{},
|
|
// Vulcanize DXNS modules
|
|
auction.AppModuleBasic{},
|
|
bond.AppModuleBasic{},
|
|
nameservice.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
|
|
|
|
auctiontypes.ModuleName: nil,
|
|
auctiontypes.AuctionBurnModuleAccountName: nil,
|
|
nameservicetypes.ModuleName: nil,
|
|
nameservicetypes.RecordRentModuleAccountName: nil,
|
|
nameservicetypes.AuthorityRentModuleAccountName: nil,
|
|
bondtypes.ModuleName: nil,
|
|
}
|
|
|
|
// 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
|
|
|
|
invCheckPeriod uint
|
|
|
|
// keys to access the substores
|
|
keys map[string]*sdk.KVStoreKey
|
|
tkeys map[string]*sdk.TransientStoreKey
|
|
memKeys map[string]*sdk.MemoryStoreKey
|
|
|
|
// keepers
|
|
AccountKeeper authkeeper.AccountKeeper
|
|
BankKeeper bankkeeper.Keeper
|
|
CapabilityKeeper *capabilitykeeper.Keeper
|
|
StakingKeeper stakingkeeper.Keeper
|
|
SlashingKeeper slashingkeeper.Keeper
|
|
MintKeeper mintkeeper.Keeper
|
|
DistrKeeper distrkeeper.Keeper
|
|
GovKeeper govkeeper.Keeper
|
|
CrisisKeeper crisiskeeper.Keeper
|
|
UpgradeKeeper upgradekeeper.Keeper
|
|
ParamsKeeper paramskeeper.Keeper
|
|
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
|
|
|
|
// DXNS keepers
|
|
AuctionKeeper auctionkeeper.Keeper
|
|
BondKeeper bondkeeper.Keeper
|
|
NameServiceKeeper nameservicekeeper.Keeper
|
|
NameServiceRecordKeeper nameservicekeeper.RecordKeeper
|
|
|
|
// 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 dbm.DB,
|
|
traceStore io.Writer,
|
|
loadLatest bool,
|
|
skipUpgradeHeights map[int64]bool,
|
|
homePath string,
|
|
invCheckPeriod uint,
|
|
encodingConfig simappparams.EncodingConfig,
|
|
appOpts servertypes.AppOptions,
|
|
baseAppOptions ...func(*baseapp.BaseApp),
|
|
) *EthermintApp {
|
|
appCodec := encodingConfig.Marshaler
|
|
cdc := encodingConfig.Amino
|
|
interfaceRegistry := encodingConfig.InterfaceRegistry
|
|
|
|
// NOTE we use custom transaction decoder that supports the sdk.Tx interface instead of sdk.StdTx
|
|
bApp := baseapp.NewBaseApp(
|
|
appName,
|
|
logger,
|
|
db,
|
|
encodingConfig.TxConfig.TxDecoder(),
|
|
baseAppOptions...,
|
|
)
|
|
bApp.SetCommitMultiStoreTracer(traceStore)
|
|
bApp.SetVersion(version.Version)
|
|
bApp.SetInterfaceRegistry(interfaceRegistry)
|
|
|
|
keys := sdk.NewKVStoreKeys(
|
|
// SDK keys
|
|
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
|
|
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
|
|
govtypes.StoreKey, paramstypes.StoreKey, upgradetypes.StoreKey,
|
|
evidencetypes.StoreKey, capabilitytypes.StoreKey,
|
|
feegrant.StoreKey, authzkeeper.StoreKey,
|
|
// ibc keys
|
|
ibchost.StoreKey, ibctransfertypes.StoreKey,
|
|
// ethermint keys
|
|
evmtypes.StoreKey, feemarkettypes.StoreKey,
|
|
// dxns keys
|
|
auctiontypes.StoreKey,
|
|
bondtypes.StoreKey,
|
|
nameservicetypes.StoreKey,
|
|
)
|
|
|
|
// Add the EVM transient store key
|
|
tkeys := sdk.NewTransientStoreKeys(paramstypes.TStoreKey, evmtypes.TransientKey)
|
|
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey)
|
|
|
|
app := &EthermintApp{
|
|
BaseApp: bApp,
|
|
cdc: cdc,
|
|
appCodec: appCodec,
|
|
interfaceRegistry: interfaceRegistry,
|
|
invCheckPeriod: invCheckPeriod,
|
|
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(paramskeeper.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,
|
|
)
|
|
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.ModuleAccountAddrs(),
|
|
)
|
|
app.SlashingKeeper = slashingkeeper.NewKeeper(
|
|
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
|
|
)
|
|
app.CrisisKeeper = crisiskeeper.NewKeeper(
|
|
app.GetSubspace(crisistypes.ModuleName), invCheckPeriod, app.BankKeeper, authtypes.FeeCollectorName,
|
|
)
|
|
app.FeeGrantKeeper = feegrantkeeper.NewKeeper(appCodec, keys[feegrant.StoreKey], app.AccountKeeper)
|
|
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp)
|
|
|
|
// 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.BaseApp.MsgServiceRouter())
|
|
|
|
tracer := cast.ToString(appOpts.Get(srvflags.EVMTracer))
|
|
|
|
// Create Ethermint keepers
|
|
app.FeeMarketKeeper = feemarketkeeper.NewKeeper(
|
|
appCodec, keys[feemarkettypes.StoreKey], app.GetSubspace(feemarkettypes.ModuleName),
|
|
)
|
|
|
|
// Create Vulcanize dxns keepers
|
|
app.AuctionKeeper = auctionkeeper.NewKeeper(
|
|
app.AccountKeeper, app.BankKeeper, keys[auctiontypes.StoreKey],
|
|
appCodec, app.GetSubspace(auctiontypes.ModuleName),
|
|
)
|
|
|
|
app.NameServiceRecordKeeper = nameservicekeeper.NewRecordKeeper(app.AuctionKeeper, keys[nameservicetypes.StoreKey], appCodec)
|
|
|
|
app.AuctionKeeper.SetUsageKeepers([]auctiontypes.AuctionUsageKeeper{app.NameServiceRecordKeeper})
|
|
|
|
app.BondKeeper = bondkeeper.NewKeeper(
|
|
appCodec, app.AccountKeeper, app.BankKeeper,
|
|
[]bondtypes.BondUsageKeeper{app.NameServiceRecordKeeper}, keys[bondtypes.StoreKey], app.GetSubspace(bondtypes.ModuleName),
|
|
)
|
|
|
|
app.NameServiceKeeper = nameservicekeeper.NewKeeper(
|
|
appCodec, app.AccountKeeper, app.BankKeeper,
|
|
app.NameServiceRecordKeeper, app.BondKeeper, app.AuctionKeeper,
|
|
keys[nameservicetypes.StoreKey], app.GetSubspace(nameservicetypes.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 := govtypes.NewRouter()
|
|
govRouter.AddRoute(govtypes.RouterKey, govtypes.ProposalHandler).
|
|
AddRoute(paramproposal.RouterKey, params.NewParamChangeProposalHandler(app.ParamsKeeper)).
|
|
AddRoute(distrtypes.RouterKey, distr.NewCommunityPoolSpendProposalHandler(app.DistrKeeper)).
|
|
AddRoute(upgradetypes.RouterKey, upgrade.NewSoftwareUpgradeProposalHandler(app.UpgradeKeeper)).
|
|
AddRoute(ibchost.RouterKey, ibcclient.NewClientProposalHandler(app.IBCKeeper.ClientKeeper))
|
|
|
|
govKeeper := govkeeper.NewKeeper(
|
|
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
|
|
&stakingKeeper, govRouter,
|
|
)
|
|
|
|
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),
|
|
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),
|
|
transferModule,
|
|
// Ethermint app modules
|
|
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
|
feemarket.NewAppModule(app.FeeMarketKeeper),
|
|
// DXNs modules
|
|
auction.NewAppModule(appCodec, app.AuctionKeeper),
|
|
bond.NewAppModule(appCodec, app.BondKeeper),
|
|
nameservice.NewAppModule(app.NameServiceKeeper),
|
|
)
|
|
|
|
// 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,
|
|
ibchost.ModuleName,
|
|
// no-op modules
|
|
ibctransfertypes.ModuleName,
|
|
authtypes.ModuleName,
|
|
banktypes.ModuleName,
|
|
govtypes.ModuleName,
|
|
crisistypes.ModuleName,
|
|
genutiltypes.ModuleName,
|
|
authz.ModuleName,
|
|
feegrant.ModuleName,
|
|
paramstypes.ModuleName,
|
|
vestingtypes.ModuleName,
|
|
// DXNS modules
|
|
auctiontypes.ModuleName,
|
|
bondtypes.ModuleName,
|
|
nameservicetypes.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
|
|
ibchost.ModuleName,
|
|
ibctransfertypes.ModuleName,
|
|
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,
|
|
// DXNS modules
|
|
auctiontypes.ModuleName,
|
|
bondtypes.ModuleName,
|
|
nameservicetypes.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,
|
|
ibchost.ModuleName,
|
|
genutiltypes.ModuleName,
|
|
evidencetypes.ModuleName,
|
|
ibctransfertypes.ModuleName,
|
|
authz.ModuleName,
|
|
feegrant.ModuleName,
|
|
paramstypes.ModuleName,
|
|
upgradetypes.ModuleName,
|
|
vestingtypes.ModuleName,
|
|
// Ethermint modules
|
|
evmtypes.ModuleName,
|
|
feemarkettypes.ModuleName,
|
|
// DXNS modules
|
|
auctiontypes.ModuleName,
|
|
bondtypes.ModuleName,
|
|
nameservicetypes.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.Router(), app.QueryRouter(), encodingConfig.Amino)
|
|
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), 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),
|
|
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),
|
|
transferModule,
|
|
evm.NewAppModule(app.EvmKeeper, app.AccountKeeper),
|
|
feemarket.NewAppModule(app.FeeMarketKeeper),
|
|
)
|
|
|
|
app.sm.RegisterStoreDecoders()
|
|
|
|
// initialize stores
|
|
app.MountKVStores(keys)
|
|
app.MountTransientStores(tkeys)
|
|
app.MountMemoryStores(memKeys)
|
|
|
|
// initialize BaseApp
|
|
app.SetInitChainer(app.InitChainer)
|
|
app.SetBeginBlocker(app.BeginBlocker)
|
|
|
|
// use Ethermint's custom AnteHandler
|
|
|
|
maxGasWanted := cast.ToUint64(appOpts.Get(srvflags.EVMMaxTxGasWanted))
|
|
options := ante.HandlerOptions{
|
|
AccountKeeper: app.AccountKeeper,
|
|
BankKeeper: app.BankKeeper,
|
|
EvmKeeper: app.EvmKeeper,
|
|
FeegrantKeeper: app.FeeGrantKeeper,
|
|
IBCKeeper: app.IBCKeeper,
|
|
FeeMarketKeeper: app.FeeMarketKeeper,
|
|
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
|
|
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
|
|
MaxTxGasWanted: maxGasWanted,
|
|
}
|
|
|
|
if err := options.Validate(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
app.SetAnteHandler(ante.NewAnteHandler(options))
|
|
app.SetEndBlocker(app.EndBlocker)
|
|
|
|
if loadLatest {
|
|
if err := app.LoadLatestVersion(); err != nil {
|
|
tmos.Exit(err.Error())
|
|
}
|
|
}
|
|
|
|
app.ScopedIBCKeeper = scopedIBCKeeper
|
|
app.ScopedTransferKeeper = scopedTransferKeeper
|
|
|
|
return app
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
|
|
// 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) *sdk.KVStoreKey {
|
|
return app.keys[storeKey]
|
|
}
|
|
|
|
// GetTKey returns the TransientStoreKey for the provided store key.
|
|
//
|
|
// NOTE: This is solely to be used for testing purposes.
|
|
func (app *EthermintApp) GetTKey(storeKey string) *sdk.TransientStoreKey {
|
|
return app.tkeys[storeKey]
|
|
}
|
|
|
|
// GetMemKey returns the MemStoreKey for the provided mem key.
|
|
//
|
|
// NOTE: This is solely used for testing purposes.
|
|
func (app *EthermintApp) GetMemKey(storeKey string) *sdk.MemoryStoreKey {
|
|
return app.memKeys[storeKey]
|
|
}
|
|
|
|
// GetSubspace returns a param subspace for a given module name.
|
|
//
|
|
// NOTE: This is solely to be used for testing purposes.
|
|
func (app *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 sdk.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(govtypes.ParamKeyTable())
|
|
paramsKeeper.Subspace(crisistypes.ModuleName)
|
|
paramsKeeper.Subspace(ibctransfertypes.ModuleName)
|
|
paramsKeeper.Subspace(ibchost.ModuleName)
|
|
// ethermint subspaces
|
|
paramsKeeper.Subspace(evmtypes.ModuleName)
|
|
paramsKeeper.Subspace(feemarkettypes.ModuleName)
|
|
// dxns subspaces
|
|
paramsKeeper.Subspace(auctiontypes.ModuleName)
|
|
paramsKeeper.Subspace(bondtypes.ModuleName)
|
|
paramsKeeper.Subspace(nameservicetypes.ModuleName)
|
|
return paramsKeeper
|
|
}
|