Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: decouple x/capability from simapp #12256

Merged
merged 10 commits into from
Jun 16, 2022
2 changes: 1 addition & 1 deletion runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ func (a *App) Configurator() module.Configurator {
return a.configurator
}

// UnsafeFindStoreKey FindStoreKey fetches a registered StoreKey from the App in linear time.
// UnsafeFindStoreKey fetches a registered StoreKey from the App in linear time.
//
// NOTE: This should only be used in testing.
func (a *App) UnsafeFindStoreKey(storeKey string) storetypes.StoreKey {
Expand Down
37 changes: 3 additions & 34 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,9 +159,7 @@ type SimApp struct {
invCheckPeriod uint

// keys to access the substores
keys map[string]*storetypes.KVStoreKey
tkeys map[string]*storetypes.TransientStoreKey
memKeys map[string]*storetypes.MemoryStoreKey
keys map[string]*storetypes.KVStoreKey

// keepers
AccountKeeper authkeeper.AccountKeeper
Expand Down Expand Up @@ -239,9 +237,6 @@ func NewSimApp(
govtypes.StoreKey,
upgradetypes.StoreKey,
)
// NOTE: The testingkey is just mounted for testing purposes. Actual applications should
// not include this key.
app.memKeys = sdk.NewMemoryStoreKeys("testingkey")

// configure state listening capabilities using AppOptions
// we are doing nothing with the returned streamingServices and waitGroup in this case
Expand Down Expand Up @@ -322,13 +317,13 @@ func NewSimApp(
app.ModuleManager.SetOrderExportGenesis(genesisModuleOrder...)

// Uncomment if you want to set a custom migration order here.
// app.mm.SetOrderMigrations(custom order)
// app.ModuleManager.SetOrderMigrations(custom order)

app.ModuleManager.RegisterInvariants(&app.CrisisKeeper)
app.ModuleManager.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)

// RegisterUpgradeHandlers is used for registering any on-chain upgrades.
// Make sure it's called after `app.mm` and `app.configurator` are set.
// Make sure it's called after `app.ModuleManager` and `app.configurator` are set.
app.RegisterUpgradeHandlers()

// add test gRPC service for testing gRPC queries in isolation
Expand All @@ -347,7 +342,6 @@ func NewSimApp(

// initialize stores
app.MountKVStores(app.keys)
app.MountMemoryStores(app.memKeys)

// initialize BaseApp
app.SetInitChainer(app.InitChainer)
Expand Down Expand Up @@ -411,31 +405,6 @@ func (app *SimApp) GetKey(storeKey string) *storetypes.KVStoreKey {
return kvStoreKey
}

// GetTKey returns the TransientStoreKey for the provided store key.
//
// NOTE: This is solely to be used for testing purposes.
func (app *SimApp) 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 *SimApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
msk := app.memKeys[storeKey]
if msk != nil {
return msk
}

sk := app.UnsafeFindStoreKey(storeKey)
memStoreKey, ok := sk.(*storetypes.MemoryStoreKey)
if !ok {
return nil
}

return memStoreKey
}

// GetSubspace returns a param subspace for a given module name.
//
// NOTE: This is solely to be used for testing purposes.
Expand Down
40 changes: 37 additions & 3 deletions testutil/sims/app_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,30 @@ var DefaultConsensusParams = &tmproto.ConsensusParams{
// appConfig usually load from a `app.yaml` with `appconfig.LoadYAML`, defines the application configuration.
// extraOutputs defines the extra outputs to be assigned by the dependency injector (depinject).
func Setup(appConfig depinject.Config, extraOutputs ...interface{}) (*runtime.App, error) {
return SetupWithBaseAppOption(appConfig, nil, false, extraOutputs...)
}

// SetupAtGenesis initializes a new runtime.App at genesis. A Nop logger is set in runtime.App.
// appConfig usually load from a `app.yaml` with `appconfig.LoadYAML`, defines the application configuration.
// extraOutputs defines the extra outputs to be assigned by the dependency injector (depinject).
func SetupAtGenesis(appConfig depinject.Config, extraOutputs ...interface{}) (*runtime.App, error) {
return SetupWithBaseAppOption(appConfig, nil, true, extraOutputs...)
}

// SetupWithBaseAppOption initializes a new runtime.App. A Nop logger is set in runtime.App.
// appConfig usually load from a `app.yaml` with `appconfig.LoadYAML`, defines the application configuration.
// baseAppOption defines the additional operations that must be run on baseapp before app start.
// extraOutputs defines the extra outputs to be assigned by the dependency injector (depinject).
// genesis defines if the app started should already have produced block or not.
func SetupWithBaseAppOption(appConfig depinject.Config, baseAppOption runtime.BaseAppOption, genesis bool, extraOutputs ...interface{}) (*runtime.App, error) {
//
// create app
//
var appBuilder *runtime.AppBuilder
var codec codec.Codec
var (
app *runtime.App
appBuilder *runtime.AppBuilder
codec codec.Codec
)

if err := depinject.Inject(
appConfig,
Expand All @@ -68,7 +87,11 @@ func Setup(appConfig depinject.Config, extraOutputs ...interface{}) (*runtime.Ap
return nil, fmt.Errorf("failed to inject dependencies: %w", err)
}

app := appBuilder.Build(log.NewNopLogger(), dbm.NewMemDB(), nil)
if baseAppOption != nil {
app = appBuilder.Build(log.NewNopLogger(), dbm.NewMemDB(), nil, baseAppOption)
} else {
app = appBuilder.Build(log.NewNopLogger(), dbm.NewMemDB(), nil)
}
if err := app.Load(true); err != nil {
return nil, fmt.Errorf("failed to load app: %w", err)
}
Expand Down Expand Up @@ -114,6 +137,17 @@ func Setup(appConfig depinject.Config, extraOutputs ...interface{}) (*runtime.Ap
},
)

// commit genesis changes
if !genesis {
app.Commit()
app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{
Height: app.LastBlockHeight() + 1,
AppHash: app.LastCommitID().Hash,
ValidatorsHash: valSet.Hash(),
NextValidatorsHash: valSet.Hash(),
}})
}

return app, nil
}

Expand Down
35 changes: 20 additions & 15 deletions x/capability/capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,44 @@ import (
abci "github.com/tendermint/tendermint/abci/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/runtime"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/capability"
"github.com/cosmos/cosmos-sdk/x/capability/keeper"
"github.com/cosmos/cosmos-sdk/x/capability/testutil"
"github.com/cosmos/cosmos-sdk/x/capability/types"
)

type CapabilityTestSuite struct {
suite.Suite

app *runtime.App
cdc codec.Codec
ctx sdk.Context
app *simapp.SimApp
keeper *keeper.Keeper
module module.AppModule
memKey *storetypes.MemoryStoreKey
}

func (suite *CapabilityTestSuite) SetupTest() {
checkTx := false
app := simapp.Setup(suite.T(), checkTx)
cdc := app.AppCodec()

// create new keeper so we can define custom scoping before init and seal
keeper := keeper.NewKeeper(cdc, app.GetKey(types.StoreKey), app.GetMemKey(types.MemStoreKey))
suite.memKey = storetypes.NewMemoryStoreKey("testingkey")

app, err := simtestutil.SetupWithBaseAppOption(testutil.AppConfig,
func(ba *baseapp.BaseApp) {
ba.MountStores(suite.memKey)
},
false,
&suite.cdc,
&suite.keeper,
)
suite.Require().NoError(err)

suite.app = app
suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1})
suite.keeper = keeper
suite.cdc = cdc
suite.module = capability.NewAppModule(cdc, *keeper, true)
suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{Height: 1})
}

// The following test case mocks a specific bug discovered in https://github.com/cosmos/cosmos-sdk/issues/9800
Expand All @@ -52,7 +57,7 @@ func (suite *CapabilityTestSuite) TestInitializeMemStore() {
suite.Require().NotNil(cap1)

// mock statesync by creating new keeper that shares persistent state but loses in-memory map
newKeeper := keeper.NewKeeper(suite.cdc, suite.app.GetKey(types.StoreKey), suite.app.GetMemKey("testingkey"))
newKeeper := keeper.NewKeeper(suite.cdc, suite.app.UnsafeFindStoreKey(types.StoreKey).(*storetypes.KVStoreKey), suite.memKey)
newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName)

// Mock App startup
Expand Down
13 changes: 5 additions & 8 deletions x/capability/genesis_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package capability_test

import (
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
dbm "github.com/tendermint/tm-db"

"github.com/cosmos/cosmos-sdk/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/capability"
"github.com/cosmos/cosmos-sdk/x/capability/keeper"
"github.com/cosmos/cosmos-sdk/x/capability/types"
"github.com/cosmos/cosmos-sdk/x/capability/testutil"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)

Expand All @@ -33,11 +31,10 @@ func (suite *CapabilityTestSuite) TestGenesis() {

// create new app that does not share persistent or in-memory state
// and initialize app from exported genesis state above.
db := dbm.NewMemDB()
encCdc := simapp.MakeTestEncodingConfig()
newApp := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5, encCdc, simapp.EmptyAppOptions{})
var newKeeper *keeper.Keeper
newApp, err := simtestutil.SetupAtGenesis(testutil.AppConfig, &newKeeper)
suite.Require().NoError(err)

newKeeper := keeper.NewKeeper(suite.cdc, newApp.GetKey(types.StoreKey), newApp.GetMemKey(types.MemStoreKey))
newSk1 := newKeeper.ScopeToModule(banktypes.ModuleName)
newSk2 := newKeeper.ScopeToModule(stakingtypes.ModuleName)
deliverCtx, _ := newApp.BaseApp.NewUncachedContext(false, tmproto.Header{}).WithBlockGasMeter(sdk.NewInfiniteGasMeter()).CacheContext()
Expand Down
18 changes: 7 additions & 11 deletions x/capability/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/cosmos/cosmos-sdk/simapp"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/cosmos/cosmos-sdk/x/capability/keeper"
"github.com/cosmos/cosmos-sdk/x/capability/testutil"
"github.com/cosmos/cosmos-sdk/x/capability/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
Expand All @@ -19,21 +20,16 @@ type KeeperTestSuite struct {
suite.Suite

ctx sdk.Context
app *simapp.SimApp
keeper *keeper.Keeper
}

func (suite *KeeperTestSuite) SetupTest() {
checkTx := false
app := simapp.Setup(suite.T(), checkTx)
cdc := app.AppCodec()

// create new keeper so we can define custom scoping before init and seal
keeper := keeper.NewKeeper(cdc, app.GetKey(types.StoreKey), app.GetMemKey(types.MemStoreKey))
app, err := simtestutil.Setup(testutil.AppConfig,
&suite.keeper,
)
suite.Require().NoError(err)

suite.app = app
suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1})
suite.keeper = keeper
suite.ctx = app.BaseApp.NewContext(false, tmproto.Header{Height: 1})
}

func (suite *KeeperTestSuite) TestSeal() {
Expand Down
67 changes: 44 additions & 23 deletions x/capability/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/depinject"
"github.com/cosmos/cosmos-sdk/runtime"
store "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/telemetry"
Expand Down Expand Up @@ -165,29 +166,6 @@ func (am AppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []abci.Valid
return []abci.ValidatorUpdate{}
}

func init() {
appmodule.Register(&modulev1.Module{},
appmodule.Provide(
provideModuleBasic,
provideModule,
))
}

func provideModuleBasic() runtime.AppModuleBasicWrapper {
return runtime.WrapAppModuleBasic(AppModuleBasic{})
}

func provideModule(
kvStoreKey *store.KVStoreKey,
memStoreKey *store.MemoryStoreKey,
cdc codec.Codec,
config *modulev1.Module,
) (*keeper.Keeper, runtime.AppModuleWrapper) {
k := keeper.NewKeeper(cdc, kvStoreKey, memStoreKey)
m := NewAppModule(cdc, *k, config.SealKeeper)
return k, runtime.WrapAppModule(m)
}

// GenerateGenesisState creates a randomized GenState of the capability module.
func (AppModule) GenerateGenesisState(simState *module.SimulationState) {
simulation.RandomizedGenState(simState)
Expand All @@ -212,3 +190,46 @@ func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation {
return nil
}

//
// New App Wiring Setup
//

func init() {
appmodule.Register(&modulev1.Module{},
appmodule.Provide(
provideModuleBasic,
provideModule,
))
}

func provideModuleBasic() runtime.AppModuleBasicWrapper {
return runtime.WrapAppModuleBasic(AppModuleBasic{})
}

type capabilityInputs struct {
depinject.In

Config *modulev1.Module

KvStoreKey *store.KVStoreKey
MemStoreKey *store.MemoryStoreKey
Cdc codec.Codec
}

type capabilityOutputs struct {
depinject.Out

CapabilityKeeper *keeper.Keeper
Module runtime.AppModuleWrapper
}

func provideModule(in capabilityInputs) capabilityOutputs {
k := keeper.NewKeeper(in.Cdc, in.KvStoreKey, in.MemStoreKey)
m := NewAppModule(in.Cdc, *k, in.Config.SealKeeper)

return capabilityOutputs{
CapabilityKeeper: k,
Module: runtime.WrapAppModule(m),
}
}
9 changes: 7 additions & 2 deletions x/capability/simulation/decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ import (

"github.com/stretchr/testify/require"

"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/depinject"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/kv"
"github.com/cosmos/cosmos-sdk/x/capability/simulation"
"github.com/cosmos/cosmos-sdk/x/capability/testutil"
"github.com/cosmos/cosmos-sdk/x/capability/types"
)

func TestDecodeStore(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig().Codec
var cdc codec.Codec
err := depinject.Inject(testutil.AppConfig, &cdc)
require.NoError(t, err)

dec := simulation.NewDecodeStore(cdc)

capOwners := types.CapabilityOwners{
Expand Down
Loading