feat: [ENG-792] Implement E2E Testing Framework (#107)
This commit is contained in:
@@ -0,0 +1,384 @@
|
||||
package app
|
||||
|
||||
//nolint:revive
|
||||
import (
|
||||
_ "embed"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"cosmossdk.io/depinject"
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"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"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
|
||||
_ "github.com/cosmos/cosmos-sdk/x/auth/tx/config" // import for side-effects
|
||||
"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"
|
||||
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 (
|
||||
BondDenom = sdk.DefaultBondDenom
|
||||
|
||||
// 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 = (*TestApp)(nil)
|
||||
_ servertypes.Application = (*TestApp)(nil)
|
||||
)
|
||||
|
||||
type TestApp 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
|
||||
ConsensusParamsKeeper consensuskeeper.Keeper
|
||||
}
|
||||
|
||||
func init() {
|
||||
userHomeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
DefaultNodeHome = filepath.Join(userHomeDir, ".testapp")
|
||||
}
|
||||
|
||||
func New(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
traceStore io.Writer,
|
||||
loadLatest bool,
|
||||
appOpts servertypes.AppOptions,
|
||||
baseAppOptions ...func(*baseapp.BaseApp),
|
||||
) *TestApp {
|
||||
var (
|
||||
app = &TestApp{}
|
||||
appBuilder *runtime.AppBuilder
|
||||
|
||||
// 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.ConsensusParamsKeeper,
|
||||
); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Below we could construct and set an application specific mempool and
|
||||
// ABCI 1.0 PrepareProposal and ProcessProposal handlers. These defaults are
|
||||
// already set in the SDK's BaseApp, this shows an example of how to override
|
||||
// them.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// app.App = appBuilder.Build(...)
|
||||
// nonceMempool := mempool.NewSenderNonceMempool()
|
||||
// abciPropHandler := NewDefaultProposalHandler(nonceMempool, app.App.BaseApp)
|
||||
//
|
||||
// app.App.BaseApp.SetMempool(nonceMempool)
|
||||
// app.App.BaseApp.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
|
||||
// app.App.BaseApp.SetProcessProposal(abciPropHandler.ProcessProposalHandler())
|
||||
//
|
||||
// Alternatively, you can construct BaseApp options, append those to
|
||||
// baseAppOptions and pass them to the appBuilder.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// prepareOpt = func(app *baseapp.BaseApp) {
|
||||
// abciPropHandler := baseapp.NewDefaultProposalHandler(nonceMempool, app)
|
||||
// app.SetPrepareProposal(abciPropHandler.PrepareProposalHandler())
|
||||
// }
|
||||
// baseAppOptions = append(baseAppOptions, prepareOpt)
|
||||
|
||||
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{})
|
||||
|
||||
// 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 *TestApp) 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 *TestApp) 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 *TestApp) AppCodec() codec.Codec {
|
||||
return app.appCodec
|
||||
}
|
||||
|
||||
// InterfaceRegistry returns SimApp's InterfaceRegistry
|
||||
func (app *TestApp) InterfaceRegistry() codectypes.InterfaceRegistry {
|
||||
return app.interfaceRegistry
|
||||
}
|
||||
|
||||
// TxConfig returns SimApp's TxConfig
|
||||
func (app *TestApp) 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 *TestApp) GetKey(storeKey string) *storetypes.KVStoreKey {
|
||||
sk := app.UnsafeFindStoreKey(storeKey)
|
||||
kvStoreKey, ok := sk.(*storetypes.KVStoreKey)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return kvStoreKey
|
||||
}
|
||||
|
||||
func (app *TestApp) 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 *TestApp) GetSubspace(moduleName string) paramstypes.Subspace {
|
||||
subspace, _ := app.ParamsKeeper.GetSubspace(moduleName)
|
||||
return subspace
|
||||
}
|
||||
|
||||
// SimulationManager implements the SimulationApp interface
|
||||
func (app *TestApp) SimulationManager() *module.SimulationManager {
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterAPIRoutes registers all application module routes with the provided
|
||||
// API server.
|
||||
func (app *TestApp) 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
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
|
||||
appv1alpha1 "cosmossdk.io/api/cosmos/app/v1alpha1"
|
||||
authmodulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
|
||||
authzmodulev1 "cosmossdk.io/api/cosmos/authz/module/v1"
|
||||
bankmodulev1 "cosmossdk.io/api/cosmos/bank/module/v1"
|
||||
capabilitymodulev1 "cosmossdk.io/api/cosmos/capability/module/v1"
|
||||
consensusmodulev1 "cosmossdk.io/api/cosmos/consensus/module/v1"
|
||||
crisismodulev1 "cosmossdk.io/api/cosmos/crisis/module/v1"
|
||||
distrmodulev1 "cosmossdk.io/api/cosmos/distribution/module/v1"
|
||||
evidencemodulev1 "cosmossdk.io/api/cosmos/evidence/module/v1"
|
||||
feegrantmodulev1 "cosmossdk.io/api/cosmos/feegrant/module/v1"
|
||||
genutilmodulev1 "cosmossdk.io/api/cosmos/genutil/module/v1"
|
||||
govmodulev1 "cosmossdk.io/api/cosmos/gov/module/v1"
|
||||
groupmodulev1 "cosmossdk.io/api/cosmos/group/module/v1"
|
||||
mintmodulev1 "cosmossdk.io/api/cosmos/mint/module/v1"
|
||||
paramsmodulev1 "cosmossdk.io/api/cosmos/params/module/v1"
|
||||
slashingmodulev1 "cosmossdk.io/api/cosmos/slashing/module/v1"
|
||||
stakingmodulev1 "cosmossdk.io/api/cosmos/staking/module/v1"
|
||||
txconfigv1 "cosmossdk.io/api/cosmos/tx/config/v1"
|
||||
upgrademodulev1 "cosmossdk.io/api/cosmos/upgrade/module/v1"
|
||||
vestingmodulev1 "cosmossdk.io/api/cosmos/vesting/module/v1"
|
||||
"cosmossdk.io/core/appconfig"
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
|
||||
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
|
||||
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
|
||||
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
|
||||
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/feegrant"
|
||||
genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/group"
|
||||
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
|
||||
paramstypes "github.com/cosmos/cosmos-sdk/x/params/types"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// NOTE: The genutils module must occur after staking so that pools are
|
||||
// properly initialized with tokens from genesis accounts.
|
||||
// NOTE: The genutils module must also occur after auth so that it can access the params from auth.
|
||||
// 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.
|
||||
genesisModuleOrder = []string{
|
||||
capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName,
|
||||
distrtypes.ModuleName, stakingtypes.ModuleName, slashingtypes.ModuleName, govtypes.ModuleName,
|
||||
minttypes.ModuleName, crisistypes.ModuleName, genutiltypes.ModuleName, evidencetypes.ModuleName, authz.ModuleName,
|
||||
feegrant.ModuleName, group.ModuleName, paramstypes.ModuleName, upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName, consensustypes.ModuleName,
|
||||
}
|
||||
|
||||
// module account permissions
|
||||
moduleAccPerms = []*authmodulev1.ModuleAccountPermission{
|
||||
{Account: authtypes.FeeCollectorName},
|
||||
{Account: distrtypes.ModuleName},
|
||||
{Account: minttypes.ModuleName, Permissions: []string{authtypes.Minter}},
|
||||
{Account: stakingtypes.BondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
|
||||
{Account: stakingtypes.NotBondedPoolName, Permissions: []string{authtypes.Burner, stakingtypes.ModuleName}},
|
||||
{Account: govtypes.ModuleName, Permissions: []string{authtypes.Burner}},
|
||||
}
|
||||
|
||||
// blocked account addresses
|
||||
blockAccAddrs = []string{
|
||||
authtypes.FeeCollectorName,
|
||||
distrtypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
stakingtypes.BondedPoolName,
|
||||
stakingtypes.NotBondedPoolName,
|
||||
// We allow the following module accounts to receive funds:
|
||||
// govtypes.ModuleName
|
||||
}
|
||||
|
||||
// application configuration (used by depinject)
|
||||
AppConfig = appconfig.Compose(&appv1alpha1.Config{
|
||||
Modules: []*appv1alpha1.ModuleConfig{
|
||||
{
|
||||
Name: "runtime",
|
||||
Config: appconfig.WrapAny(&runtimev1alpha1.Module{
|
||||
AppName: "TestApp",
|
||||
// During begin block slashing happens after distr.BeginBlocker so that
|
||||
// there is nothing left over in the validator fee pool, so as to keep the
|
||||
// CanWithdrawInvariant invariant.
|
||||
// NOTE: staking module is required if HistoricalEntries param > 0
|
||||
// NOTE: capability module's beginblocker must come before any modules using capabilities (e.g. IBC)
|
||||
BeginBlockers: []string{
|
||||
upgradetypes.ModuleName,
|
||||
capabilitytypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
distrtypes.ModuleName,
|
||||
slashingtypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
crisistypes.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
group.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
},
|
||||
EndBlockers: []string{
|
||||
crisistypes.ModuleName,
|
||||
govtypes.ModuleName,
|
||||
stakingtypes.ModuleName,
|
||||
capabilitytypes.ModuleName,
|
||||
authtypes.ModuleName,
|
||||
banktypes.ModuleName,
|
||||
distrtypes.ModuleName,
|
||||
slashingtypes.ModuleName,
|
||||
minttypes.ModuleName,
|
||||
genutiltypes.ModuleName,
|
||||
evidencetypes.ModuleName,
|
||||
authz.ModuleName,
|
||||
feegrant.ModuleName,
|
||||
group.ModuleName,
|
||||
paramstypes.ModuleName,
|
||||
consensustypes.ModuleName,
|
||||
upgradetypes.ModuleName,
|
||||
vestingtypes.ModuleName,
|
||||
},
|
||||
OverrideStoreKeys: []*runtimev1alpha1.StoreKeyConfig{
|
||||
{
|
||||
ModuleName: authtypes.ModuleName,
|
||||
KvStoreKey: "acc",
|
||||
},
|
||||
},
|
||||
InitGenesis: genesisModuleOrder,
|
||||
// When ExportGenesis is not specified, the export genesis module order
|
||||
// is equal to the init genesis order
|
||||
// ExportGenesis: genesisModuleOrder,
|
||||
// Uncomment if you want to set a custom migration order here.
|
||||
// OrderMigrations: nil,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: authtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&authmodulev1.Module{
|
||||
Bech32Prefix: "cosmos",
|
||||
ModuleAccountPermissions: moduleAccPerms,
|
||||
// By default modules authority is the governance module. This is configurable with the following:
|
||||
// Authority: "group", // A custom module authority can be set using a module name
|
||||
// Authority: "cosmos1cwwv22j5ca08ggdv9c2uky355k908694z577tv", // or a specific address
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: vestingtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&vestingmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: banktypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&bankmodulev1.Module{
|
||||
BlockedModuleAccountsOverride: blockAccAddrs,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: stakingtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&stakingmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: slashingtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&slashingmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: paramstypes.ModuleName,
|
||||
Config: appconfig.WrapAny(¶msmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: "tx",
|
||||
Config: appconfig.WrapAny(&txconfigv1.Config{}),
|
||||
},
|
||||
{
|
||||
Name: genutiltypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&genutilmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: authz.ModuleName,
|
||||
Config: appconfig.WrapAny(&authzmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: upgradetypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&upgrademodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: distrtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&distrmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: capabilitytypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&capabilitymodulev1.Module{
|
||||
SealKeeper: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: evidencetypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&evidencemodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: minttypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&mintmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: group.ModuleName,
|
||||
Config: appconfig.WrapAny(&groupmodulev1.Module{
|
||||
MaxExecutionPeriod: durationpb.New(time.Second * 1209600),
|
||||
MaxMetadataLen: 255,
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: feegrant.ModuleName,
|
||||
Config: appconfig.WrapAny(&feegrantmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: govtypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&govmodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: crisistypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&crisismodulev1.Module{}),
|
||||
},
|
||||
{
|
||||
Name: consensustypes.ModuleName,
|
||||
Config: appconfig.WrapAny(&consensusmodulev1.Module{}),
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
@@ -0,0 +1,201 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
||||
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/staking"
|
||||
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
|
||||
)
|
||||
|
||||
// ExportAppStateAndValidators exports the state of the application for a genesis
|
||||
// file.
|
||||
func (app *TestApp) ExportAppStateAndValidators(forZeroHeight bool, jailAllowedAddrs []string, modulesToExport []string) (servertypes.ExportedApp, error) {
|
||||
// as if they could withdraw from the start of the next block
|
||||
ctx := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
|
||||
|
||||
// We export at last height + 1, because that's the height at which
|
||||
// Tendermint will start InitChain.
|
||||
height := app.LastBlockHeight() + 1
|
||||
if forZeroHeight {
|
||||
height = 0
|
||||
app.prepForZeroHeightGenesis(ctx, jailAllowedAddrs)
|
||||
}
|
||||
|
||||
genState := app.ModuleManager.ExportGenesisForModules(ctx, app.appCodec, modulesToExport)
|
||||
appState, err := json.MarshalIndent(genState, "", " ")
|
||||
if err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
|
||||
validators, err := staking.WriteValidators(ctx, app.StakingKeeper)
|
||||
return servertypes.ExportedApp{
|
||||
AppState: appState,
|
||||
Validators: validators,
|
||||
Height: height,
|
||||
ConsensusParams: app.BaseApp.GetConsensusParams(ctx),
|
||||
}, err
|
||||
}
|
||||
|
||||
// prepare for fresh start at zero height
|
||||
// NOTE zero height genesis is a temporary feature which will be deprecated
|
||||
//
|
||||
// in favour of export at a block height
|
||||
func (app *TestApp) prepForZeroHeightGenesis(ctx sdk.Context, jailAllowedAddrs []string) {
|
||||
applyAllowedAddrs := false
|
||||
|
||||
// check if there is a allowed address list
|
||||
if len(jailAllowedAddrs) > 0 {
|
||||
applyAllowedAddrs = true
|
||||
}
|
||||
|
||||
allowedAddrsMap := make(map[string]bool)
|
||||
|
||||
for _, addr := range jailAllowedAddrs {
|
||||
_, err := sdk.ValAddressFromBech32(addr)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
allowedAddrsMap[addr] = true
|
||||
}
|
||||
|
||||
/* Just to be safe, assert the invariants on current state. */
|
||||
app.CrisisKeeper.AssertInvariants(ctx)
|
||||
|
||||
/* Handle fee distribution state. */
|
||||
|
||||
// withdraw all validator commission
|
||||
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
_, _ = app.DistrKeeper.WithdrawValidatorCommission(ctx, val.GetOperator())
|
||||
return false
|
||||
})
|
||||
|
||||
// withdraw all delegator rewards
|
||||
dels := app.StakingKeeper.GetAllDelegations(ctx)
|
||||
for _, delegation := range dels {
|
||||
valAddr, err := sdk.ValAddressFromBech32(delegation.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
delAddr := sdk.MustAccAddressFromBech32(delegation.DelegatorAddress)
|
||||
|
||||
_, _ = app.DistrKeeper.WithdrawDelegationRewards(ctx, delAddr, valAddr)
|
||||
}
|
||||
|
||||
// clear validator slash events
|
||||
app.DistrKeeper.DeleteAllValidatorSlashEvents(ctx)
|
||||
|
||||
// clear validator historical rewards
|
||||
app.DistrKeeper.DeleteAllValidatorHistoricalRewards(ctx)
|
||||
|
||||
// set context height to zero
|
||||
height := ctx.BlockHeight()
|
||||
ctx = ctx.WithBlockHeight(0)
|
||||
|
||||
// reinitialize all validators
|
||||
app.StakingKeeper.IterateValidators(ctx, func(_ int64, val stakingtypes.ValidatorI) (stop bool) {
|
||||
// donate any unwithdrawn outstanding reward fraction tokens to the community pool
|
||||
scraps := app.DistrKeeper.GetValidatorOutstandingRewardsCoins(ctx, val.GetOperator())
|
||||
feePool := app.DistrKeeper.GetFeePool(ctx)
|
||||
feePool.CommunityPool = feePool.CommunityPool.Add(scraps...)
|
||||
app.DistrKeeper.SetFeePool(ctx, feePool)
|
||||
|
||||
if err := app.DistrKeeper.Hooks().AfterValidatorCreated(ctx, val.GetOperator()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// reinitialize all delegations
|
||||
for _, del := range dels {
|
||||
valAddr, err := sdk.ValAddressFromBech32(del.ValidatorAddress)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
delAddr := sdk.MustAccAddressFromBech32(del.DelegatorAddress)
|
||||
|
||||
if err := app.DistrKeeper.Hooks().BeforeDelegationCreated(ctx, delAddr, valAddr); err != nil {
|
||||
// never called as BeforeDelegationCreated always returns nil
|
||||
panic(fmt.Errorf("error while incrementing period: %w", err))
|
||||
}
|
||||
|
||||
if err := app.DistrKeeper.Hooks().AfterDelegationModified(ctx, delAddr, valAddr); err != nil {
|
||||
// never called as AfterDelegationModified always returns nil
|
||||
panic(fmt.Errorf("error while creating a new delegation period record: %w", err))
|
||||
}
|
||||
}
|
||||
|
||||
// reset context height
|
||||
ctx = ctx.WithBlockHeight(height)
|
||||
|
||||
/* Handle staking state. */
|
||||
|
||||
// iterate through redelegations, reset creation height
|
||||
app.StakingKeeper.IterateRedelegations(ctx, func(_ int64, red stakingtypes.Redelegation) (stop bool) {
|
||||
for i := range red.Entries {
|
||||
red.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetRedelegation(ctx, red)
|
||||
return false
|
||||
})
|
||||
|
||||
// iterate through unbonding delegations, reset creation height
|
||||
app.StakingKeeper.IterateUnbondingDelegations(ctx, func(_ int64, ubd stakingtypes.UnbondingDelegation) (stop bool) {
|
||||
for i := range ubd.Entries {
|
||||
ubd.Entries[i].CreationHeight = 0
|
||||
}
|
||||
app.StakingKeeper.SetUnbondingDelegation(ctx, ubd)
|
||||
return false
|
||||
})
|
||||
|
||||
// Iterate through validators by power descending, reset bond heights, and
|
||||
// update bond intra-tx counters.
|
||||
store := ctx.KVStore(app.GetKey(stakingtypes.StoreKey))
|
||||
iter := sdk.KVStoreReversePrefixIterator(store, stakingtypes.ValidatorsKey)
|
||||
counter := int16(0)
|
||||
|
||||
for ; iter.Valid(); iter.Next() {
|
||||
addr := sdk.ValAddress(stakingtypes.AddressFromValidatorsKey(iter.Key()))
|
||||
validator, found := app.StakingKeeper.GetValidator(ctx, addr)
|
||||
if !found {
|
||||
panic("expected validator, not found")
|
||||
}
|
||||
|
||||
validator.UnbondingHeight = 0
|
||||
if applyAllowedAddrs && !allowedAddrsMap[addr.String()] {
|
||||
validator.Jailed = true
|
||||
}
|
||||
|
||||
app.StakingKeeper.SetValidator(ctx, validator)
|
||||
counter++
|
||||
}
|
||||
|
||||
if err := iter.Close(); err != nil {
|
||||
app.Logger().Error("error while closing the key-value store reverse prefix iterator: ", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
/* Handle slashing state. */
|
||||
|
||||
// reset start height on signing infos
|
||||
app.SlashingKeeper.IterateValidatorSigningInfos(
|
||||
ctx,
|
||||
func(addr sdk.ConsAddress, info slashingtypes.ValidatorSigningInfo) (stop bool) {
|
||||
info.StartHeight = 0
|
||||
app.SlashingKeeper.SetValidatorSigningInfo(ctx, addr, info)
|
||||
return false
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package params
|
||||
|
||||
import (
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/codec/types"
|
||||
)
|
||||
|
||||
// EncodingConfig specifies the concrete encoding types to use for a given app.
|
||||
// This is provided for compatibility between protobuf and amino implementations.
|
||||
type EncodingConfig struct {
|
||||
InterfaceRegistry types.InterfaceRegistry
|
||||
Codec codec.Codec
|
||||
TxConfig client.TxConfig
|
||||
Amino *codec.LegacyAmino
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
dbm "github.com/cometbft/cometbft-db"
|
||||
tmcfg "github.com/cometbft/cometbft/config"
|
||||
"github.com/cometbft/cometbft/libs/log"
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/config"
|
||||
"github.com/cosmos/cosmos-sdk/client/debug"
|
||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/client/pruning"
|
||||
"github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
servertypes "github.com/cosmos/cosmos-sdk/server/types"
|
||||
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/crisis"
|
||||
genutilcli "github.com/cosmos/cosmos-sdk/x/genutil/client/cli"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
"github.com/skip-mev/pob/tests/app/params"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func NewRootCmd() *cobra.Command {
|
||||
// we "pre"-instantiate the application for getting the injected/configured encoding configuration
|
||||
testApp := app.New(log.NewNopLogger(), dbm.NewMemDB(), nil, true, simtestutil.NewAppOptionsWithFlagHome(app.DefaultNodeHome))
|
||||
encodingConfig := params.EncodingConfig{
|
||||
InterfaceRegistry: testApp.InterfaceRegistry(),
|
||||
Codec: testApp.AppCodec(),
|
||||
TxConfig: testApp.TxConfig(),
|
||||
Amino: testApp.LegacyAmino(),
|
||||
}
|
||||
|
||||
initClientCtx := client.Context{}.
|
||||
WithCodec(encodingConfig.Codec).
|
||||
WithInterfaceRegistry(encodingConfig.InterfaceRegistry).
|
||||
WithTxConfig(encodingConfig.TxConfig).
|
||||
WithLegacyAmino(encodingConfig.Amino).
|
||||
WithInput(os.Stdin).
|
||||
WithAccountRetriever(types.AccountRetriever{}).
|
||||
WithHomeDir(app.DefaultNodeHome).
|
||||
WithViper("")
|
||||
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "testappd",
|
||||
Short: "POB testing application",
|
||||
PersistentPreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
// set the default command outputs
|
||||
cmd.SetOut(cmd.OutOrStdout())
|
||||
cmd.SetErr(cmd.ErrOrStderr())
|
||||
|
||||
initClientCtx, err := client.ReadPersistentCommandFlags(initClientCtx, cmd.Flags())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
initClientCtx, err = config.ReadFromClientConfig(initClientCtx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := client.SetCmdClientContextHandler(initClientCtx, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
customAppTemplate, customAppConfig := initAppConfig()
|
||||
customTMConfig := initTendermintConfig()
|
||||
|
||||
return server.InterceptConfigsPreRunHandler(cmd, customAppTemplate, customAppConfig, customTMConfig)
|
||||
},
|
||||
}
|
||||
|
||||
initRootCmd(rootCmd, encodingConfig)
|
||||
|
||||
return rootCmd
|
||||
}
|
||||
|
||||
// initTendermintConfig helps to override default Tendermint Config values.
|
||||
// return tmcfg.DefaultConfig if no custom configuration is required for the application.
|
||||
func initTendermintConfig() *tmcfg.Config {
|
||||
cfg := tmcfg.DefaultConfig()
|
||||
|
||||
// these values put a higher strain on node memory
|
||||
// cfg.P2P.MaxNumInboundPeers = 100
|
||||
// cfg.P2P.MaxNumOutboundPeers = 40
|
||||
|
||||
return cfg
|
||||
}
|
||||
|
||||
// initAppConfig helps to override default appConfig template and configs.
|
||||
// return "", nil if no custom configuration is required for the application.
|
||||
func initAppConfig() (string, interface{}) {
|
||||
// The following code snippet is just for reference.
|
||||
|
||||
// WASMConfig defines configuration for the wasm module.
|
||||
type WASMConfig struct {
|
||||
// This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries
|
||||
QueryGasLimit uint64 `mapstructure:"query_gas_limit"`
|
||||
|
||||
// Address defines the gRPC-web server to listen on
|
||||
LruSize uint64 `mapstructure:"lru_size"`
|
||||
}
|
||||
|
||||
type CustomAppConfig struct {
|
||||
serverconfig.Config
|
||||
|
||||
WASM WASMConfig `mapstructure:"wasm"`
|
||||
}
|
||||
|
||||
// Optionally allow the chain developer to overwrite the SDK's default
|
||||
// server config.
|
||||
srvCfg := serverconfig.DefaultConfig()
|
||||
// The SDK's default minimum gas price is set to "" (empty value) inside
|
||||
// app.toml. If left empty by validators, the node will halt on startup.
|
||||
// However, the chain developer can set a default app.toml value for their
|
||||
// validators here.
|
||||
//
|
||||
// In summary:
|
||||
// - if you leave srvCfg.MinGasPrices = "", all validators MUST tweak their
|
||||
// own app.toml config,
|
||||
// - if you set srvCfg.MinGasPrices non-empty, validators CAN tweak their
|
||||
// own app.toml to override, or use this default value.
|
||||
//
|
||||
// In testapp, we set the min gas prices to 0.
|
||||
srvCfg.MinGasPrices = "0stake"
|
||||
// srvCfg.BaseConfig.IAVLDisableFastNode = true // disable fastnode by default
|
||||
|
||||
customAppConfig := CustomAppConfig{
|
||||
Config: *srvCfg,
|
||||
WASM: WASMConfig{
|
||||
LruSize: 1,
|
||||
QueryGasLimit: 300000,
|
||||
},
|
||||
}
|
||||
|
||||
customAppTemplate := serverconfig.DefaultConfigTemplate + `
|
||||
[wasm]
|
||||
# This is the maximum sdk gas (wasm and storage) that we allow for any x/wasm "smart" queries
|
||||
query_gas_limit = 300000
|
||||
# This is the number of wasm vm instances we keep cached in memory for speed-up
|
||||
# Warning: this is currently unstable and may lead to crashes, best to keep for 0 unless testing locally
|
||||
lru_size = 0`
|
||||
|
||||
return customAppTemplate, customAppConfig
|
||||
}
|
||||
|
||||
func initRootCmd(rootCmd *cobra.Command, encodingConfig params.EncodingConfig) {
|
||||
cfg := sdk.GetConfig()
|
||||
cfg.Seal()
|
||||
|
||||
rootCmd.AddCommand(
|
||||
genutilcli.InitCmd(app.ModuleBasics, app.DefaultNodeHome),
|
||||
debug.Cmd(),
|
||||
config.Cmd(),
|
||||
pruning.PruningCmd(newApp),
|
||||
)
|
||||
|
||||
server.AddCommands(rootCmd, app.DefaultNodeHome, newApp, appExport, addModuleInitFlags)
|
||||
|
||||
// add keybase, auxiliary RPC, query, genesis, and tx child commands
|
||||
rootCmd.AddCommand(
|
||||
rpc.StatusCommand(),
|
||||
genesisCommand(encodingConfig),
|
||||
queryCommand(),
|
||||
txCommand(),
|
||||
keys.Commands(app.DefaultNodeHome),
|
||||
)
|
||||
}
|
||||
|
||||
func addModuleInitFlags(startCmd *cobra.Command) {
|
||||
crisis.AddModuleInitFlags(startCmd)
|
||||
}
|
||||
|
||||
func genesisCommand(encodingConfig params.EncodingConfig, cmds ...*cobra.Command) *cobra.Command {
|
||||
cmd := genutilcli.GenesisCoreCommand(encodingConfig.TxConfig, app.ModuleBasics, app.DefaultNodeHome)
|
||||
|
||||
for _, subCmd := range cmds {
|
||||
cmd.AddCommand(subCmd)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func queryCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "query",
|
||||
Aliases: []string{"q"},
|
||||
Short: "Querying subcommands",
|
||||
DisableFlagParsing: false,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
authcmd.GetAccountCmd(),
|
||||
rpc.ValidatorCommand(),
|
||||
rpc.BlockCommand(),
|
||||
authcmd.QueryTxsByEventsCmd(),
|
||||
authcmd.QueryTxCmd(),
|
||||
)
|
||||
|
||||
app.ModuleBasics.AddQueryCommands(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func txCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "tx",
|
||||
Short: "Transactions subcommands",
|
||||
DisableFlagParsing: false,
|
||||
SuggestionsMinimumDistance: 2,
|
||||
RunE: client.ValidateCmd,
|
||||
}
|
||||
|
||||
cmd.AddCommand(
|
||||
authcmd.GetSignCommand(),
|
||||
authcmd.GetSignBatchCommand(),
|
||||
authcmd.GetMultiSignCommand(),
|
||||
authcmd.GetMultiSignBatchCmd(),
|
||||
authcmd.GetValidateSignaturesCommand(),
|
||||
authcmd.GetBroadcastCommand(),
|
||||
authcmd.GetEncodeCommand(),
|
||||
authcmd.GetDecodeCommand(),
|
||||
authcmd.GetAuxToFeeCommand(),
|
||||
)
|
||||
|
||||
app.ModuleBasics.AddTxCommands(cmd)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newApp(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
traceStore io.Writer,
|
||||
appOpts servertypes.AppOptions,
|
||||
) servertypes.Application {
|
||||
baseAppOpts := server.DefaultBaseappOptions(appOpts)
|
||||
|
||||
return app.New(
|
||||
logger,
|
||||
db,
|
||||
traceStore,
|
||||
true,
|
||||
appOpts,
|
||||
baseAppOpts...,
|
||||
)
|
||||
}
|
||||
|
||||
func appExport(
|
||||
logger log.Logger,
|
||||
db dbm.DB,
|
||||
traceStore io.Writer,
|
||||
height int64,
|
||||
forZeroHeight bool,
|
||||
jailAllowedAddrs []string,
|
||||
appOpts servertypes.AppOptions,
|
||||
modulesToExport []string,
|
||||
) (servertypes.ExportedApp, error) {
|
||||
var testApp *app.TestApp
|
||||
|
||||
// this check is necessary as we use the flag in x/upgrade.
|
||||
// we can exit more gracefully by checking the flag here.
|
||||
homePath, ok := appOpts.Get(flags.FlagHome).(string)
|
||||
if !ok || homePath == "" {
|
||||
return servertypes.ExportedApp{}, errors.New("application home not set")
|
||||
}
|
||||
|
||||
viperAppOpts, ok := appOpts.(*viper.Viper)
|
||||
if !ok {
|
||||
return servertypes.ExportedApp{}, errors.New("appOpts is not viper.Viper")
|
||||
}
|
||||
|
||||
// overwrite the FlagInvCheckPeriod
|
||||
viperAppOpts.Set(server.FlagInvCheckPeriod, 1)
|
||||
appOpts = viperAppOpts
|
||||
|
||||
if height != -1 {
|
||||
testApp = app.New(logger, db, traceStore, false, appOpts)
|
||||
|
||||
if err := testApp.LoadHeight(height); err != nil {
|
||||
return servertypes.ExportedApp{}, err
|
||||
}
|
||||
} else {
|
||||
testApp = app.New(logger, db, traceStore, true, appOpts)
|
||||
}
|
||||
|
||||
return testApp.ExportAppStateAndValidators(forZeroHeight, jailAllowedAddrs, modulesToExport)
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||
"github.com/skip-mev/pob/tests/app"
|
||||
"github.com/skip-mev/pob/tests/app/testappd/cmd"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rootCmd := cmd.NewRootCmd()
|
||||
if err := svrcmd.Execute(rootCmd, "", app.DefaultNodeHome); err != nil {
|
||||
switch e := err.(type) {
|
||||
case server.ErrorCode:
|
||||
os.Exit(e.Code)
|
||||
|
||||
default:
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user