Skip to content

Commit

Permalink
feat: migrate x/capability to app wiring (#12058)
Browse files Browse the repository at this point in the history
* feat: migrate x/capability to app wiring

* added some fixes from Matt's PR + changed MemStoreKey

* fix name

* fix name

* small change

* rollback MemStoreKey change

* Revert "rollback MemStoreKey change"

This reverts commit ad191ea.

* add suggestions by @aaronc

* add IsSealed()

* fix

Co-authored-by: Aaron Craelius <[email protected]>
  • Loading branch information
facundomedica and aaronc authored Jun 2, 2022
1 parent ffa5c88 commit 17232fa
Show file tree
Hide file tree
Showing 9 changed files with 708 additions and 85 deletions.
572 changes: 572 additions & 0 deletions api/cosmos/capability/module/v1/module.pulsar.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions baseapp/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ func (app *BaseApp) MountStores(keys ...storetypes.StoreKey) {
case *storetypes.TransientStoreKey:
app.MountStore(key, storetypes.StoreTypeTransient)

case *storetypes.MemoryStoreKey:
app.MountStore(key, storetypes.StoreTypeMemory)

default:
panic(fmt.Sprintf("Unrecognized store key type :%T", key))
}
Expand Down
16 changes: 16 additions & 0 deletions proto/cosmos/capability/module/v1/module.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";

package cosmos.capability.module.v1;

import "cosmos/app/v1alpha1/module.proto";

// Module is the config object of the capability module.
message Module {
option (cosmos.app.v1alpha1.module) = {
go_import: "github.com/cosmos/cosmos-sdk/x/capability"
};

// seal_keeper defines if keeper.Seal() will run on BeginBlock() to prevent further modules from creating a scoped
// keeper. For more details check x/capability/keeper.go.
bool seal_keeper = 1;
}
144 changes: 66 additions & 78 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,102 +208,81 @@ func NewSimApp(
homePath string, invCheckPeriod uint, encodingConfig simappparams.EncodingConfig,
appOpts servertypes.AppOptions, baseAppOptions ...func(*baseapp.BaseApp),
) *SimApp {
app := &SimApp{
invCheckPeriod: invCheckPeriod,
}

var appBuilder *runtime.AppBuilder
var paramsKeeper paramskeeper.Keeper
var accountKeeper authkeeper.AccountKeeper
var bankKeeper bankkeeper.Keeper
var appCodec codec.Codec
var legacyAmino *codec.LegacyAmino
var interfaceRegistry codectypes.InterfaceRegistry

err := depinject.Inject(AppConfig,
&appBuilder,
&paramsKeeper,
&appCodec,
&legacyAmino,
&interfaceRegistry,
&accountKeeper,
&bankKeeper,
&app.ParamsKeeper,
&app.CapabilityKeeper,
&app.appCodec,
&app.legacyAmino,
&app.interfaceRegistry,
&app.AccountKeeper,
&app.BankKeeper,
)
if err != nil {
panic(err)
}

runtimeApp := appBuilder.Build(logger, db, traceStore, baseAppOptions...)
app.App = appBuilder.Build(logger, db, traceStore, baseAppOptions...)

keys := sdk.NewKVStoreKeys(
stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, capabilitytypes.StoreKey,
authzkeeper.StoreKey, nftkeeper.StoreKey, group.StoreKey,
app.keys = sdk.NewKVStoreKeys(
stakingtypes.StoreKey, minttypes.StoreKey, distrtypes.StoreKey,
slashingtypes.StoreKey, govtypes.StoreKey, upgradetypes.StoreKey,
feegrant.StoreKey, evidencetypes.StoreKey, authzkeeper.StoreKey,
nftkeeper.StoreKey, group.StoreKey,
)
// NOTE: The testingkey is just mounted for testing purposes. Actual applications should
// not include this key.
memKeys := sdk.NewMemoryStoreKeys(capabilitytypes.MemStoreKey, "testingkey")
app.memKeys = sdk.NewMemoryStoreKeys("testingkey")

// configure state listening capabilities using AppOptions
// we are doing nothing with the returned streamingServices and waitGroup in this case
if _, _, err := streaming.LoadStreamingServices(runtimeApp.BaseApp, appOpts, appCodec, keys); err != nil {
if _, _, err := streaming.LoadStreamingServices(app.App.BaseApp, appOpts, app.appCodec, app.keys); err != nil {
tmos.Exit(err.Error())
}

app := &SimApp{
App: runtimeApp,
legacyAmino: legacyAmino,
appCodec: appCodec,
interfaceRegistry: interfaceRegistry,
invCheckPeriod: invCheckPeriod,
keys: keys,
memKeys: memKeys,
}

app.ParamsKeeper = paramsKeeper
initParamsKeeper(paramsKeeper)

app.AccountKeeper = accountKeeper

app.CapabilityKeeper = capabilitykeeper.NewKeeper(appCodec, keys[capabilitytypes.StoreKey], memKeys[capabilitytypes.MemStoreKey])
// Applications that wish to enforce statically created ScopedKeepers should call `Seal` after creating
// their scoped modules in `NewApp` with `ScopeToModule`
app.CapabilityKeeper.Seal()
initParamsKeeper(app.ParamsKeeper)

// add keepers
app.BankKeeper = bankKeeper

stakingKeeper := stakingkeeper.NewKeeper(
appCodec, keys[stakingtypes.StoreKey], app.AccountKeeper, app.BankKeeper, app.GetSubspace(stakingtypes.ModuleName),
app.appCodec, app.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.appCodec, app.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,
app.appCodec, app.keys[distrtypes.StoreKey], app.GetSubspace(distrtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, authtypes.FeeCollectorName,
)
app.SlashingKeeper = slashingkeeper.NewKeeper(
appCodec, keys[slashingtypes.StoreKey], &stakingKeeper, app.GetSubspace(slashingtypes.ModuleName),
app.appCodec, app.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.FeeGrantKeeper = feegrantkeeper.NewKeeper(app.appCodec, app.keys[feegrant.StoreKey], app.AccountKeeper)

// 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.MsgServiceRouter(), app.AccountKeeper)
app.AuthzKeeper = authzkeeper.NewKeeper(app.keys[authzkeeper.StoreKey], app.appCodec, app.MsgServiceRouter(), app.AccountKeeper)

groupConfig := group.DefaultConfig()
/*
Example of setting group params:
groupConfig.MaxMetadataLen = 1000
*/
app.GroupKeeper = groupkeeper.NewKeeper(keys[group.StoreKey], appCodec, app.MsgServiceRouter(), app.AccountKeeper, groupConfig)
app.GroupKeeper = groupkeeper.NewKeeper(app.keys[group.StoreKey], app.appCodec, app.MsgServiceRouter(), app.AccountKeeper, groupConfig)

// register the proposal types
govRouter := govv1beta1.NewRouter()
Expand All @@ -317,7 +296,7 @@ func NewSimApp(
govConfig.MaxMetadataLen = 10000
*/
govKeeper := govkeeper.NewKeeper(
appCodec, keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
app.appCodec, app.keys[govtypes.StoreKey], app.GetSubspace(govtypes.ModuleName), app.AccountKeeper, app.BankKeeper,
&stakingKeeper, govRouter, app.MsgServiceRouter(), govConfig,
)

Expand All @@ -327,13 +306,13 @@ func NewSimApp(
),
)
// set the governance module account as the authority for conducting upgrades
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, keys[upgradetypes.StoreKey], appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())
app.UpgradeKeeper = upgradekeeper.NewKeeper(skipUpgradeHeights, app.keys[upgradetypes.StoreKey], app.appCodec, homePath, app.BaseApp, authtypes.NewModuleAddress(govtypes.ModuleName).String())

app.NFTKeeper = nftkeeper.NewKeeper(keys[nftkeeper.StoreKey], appCodec, app.AccountKeeper, app.BankKeeper)
app.NFTKeeper = nftkeeper.NewKeeper(app.keys[nftkeeper.StoreKey], app.appCodec, app.AccountKeeper, app.BankKeeper)

// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
appCodec, keys[evidencetypes.StoreKey], &app.StakingKeeper, app.SlashingKeeper,
app.appCodec, app.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
Expand All @@ -352,19 +331,18 @@ func NewSimApp(
encodingConfig.TxConfig,
),
vesting.NewAppModule(app.AccountKeeper, app.BankKeeper),
capability.NewAppModule(appCodec, *app.CapabilityKeeper),
crisis.NewAppModule(&app.CrisisKeeper, skipGenesisInvariants),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
feegrantmodule.NewAppModule(app.appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(app.appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(app.appCodec, app.MintKeeper, app.AccountKeeper, nil),
slashing.NewAppModule(app.appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
distr.NewAppModule(app.appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
staking.NewAppModule(app.appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
upgrade.NewAppModule(app.UpgradeKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(app.appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(app.appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(app.appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
)
if err != nil {
panic(err)
Expand Down Expand Up @@ -402,27 +380,26 @@ func NewSimApp(
// 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),
feegrantmodule.NewAppModule(appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(appCodec, app.MintKeeper, app.AccountKeeper, nil),
staking.NewAppModule(appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
distr.NewAppModule(appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
slashing.NewAppModule(appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
auth.NewAppModule(app.appCodec, app.AccountKeeper, authsims.RandomGenesisAccounts),
bank.NewAppModule(app.appCodec, app.BankKeeper, app.AccountKeeper),
feegrantmodule.NewAppModule(app.appCodec, app.AccountKeeper, app.BankKeeper, app.FeeGrantKeeper, app.interfaceRegistry),
gov.NewAppModule(app.appCodec, app.GovKeeper, app.AccountKeeper, app.BankKeeper),
mint.NewAppModule(app.appCodec, app.MintKeeper, app.AccountKeeper, nil),
staking.NewAppModule(app.appCodec, app.StakingKeeper, app.AccountKeeper, app.BankKeeper),
distr.NewAppModule(app.appCodec, app.DistrKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
slashing.NewAppModule(app.appCodec, app.SlashingKeeper, app.AccountKeeper, app.BankKeeper, app.StakingKeeper),
params.NewAppModule(app.ParamsKeeper),
evidence.NewAppModule(app.EvidenceKeeper),
authzmodule.NewAppModule(appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
authzmodule.NewAppModule(app.appCodec, app.AuthzKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
groupmodule.NewAppModule(app.appCodec, app.GroupKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
nftmodule.NewAppModule(app.appCodec, app.NFTKeeper, app.AccountKeeper, app.BankKeeper, app.interfaceRegistry),
)

app.sm.RegisterStoreDecoders()

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

// initialize BaseApp
app.SetTxDecoder(encodingConfig.TxConfig.TxDecoder())
Expand Down Expand Up @@ -547,7 +524,18 @@ func (app *SimApp) GetTKey(storeKey string) *storetypes.TransientStoreKey {
//
// NOTE: This is solely used for testing purposes.
func (app *SimApp) GetMemKey(storeKey string) *storetypes.MemoryStoreKey {
return app.memKeys[storeKey]
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.
Expand Down
7 changes: 6 additions & 1 deletion simapp/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ modules:

- name: bank
config:
"@type": cosmos.bank.module.v1.Module
"@type": cosmos.bank.module.v1.Module

- name: capability
config:
"@type": cosmos.capability.module.v1.Module
seal_keeper: true
4 changes: 2 additions & 2 deletions x/capability/capability_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func (suite *CapabilityTestSuite) SetupTest() {
suite.ctx = app.BaseApp.NewContext(checkTx, tmproto.Header{Height: 1})
suite.keeper = keeper
suite.cdc = cdc
suite.module = capability.NewAppModule(cdc, *keeper)
suite.module = capability.NewAppModule(cdc, *keeper, true)
}

// The following test case mocks a specific bug discovered in https://github.com/cosmos/cosmos-sdk/issues/9800
Expand All @@ -63,7 +63,7 @@ func (suite *CapabilityTestSuite) TestInitializeMemStore() {
// Mock app beginblock and ensure that no gas has been consumed and memstore is initialized
ctx = suite.app.BaseApp.NewContext(false, tmproto.Header{}).WithBlockGasMeter(sdk.NewGasMeter(50))
prevGas := ctx.BlockGasMeter().GasConsumed()
restartedModule := capability.NewAppModule(suite.cdc, *newKeeper)
restartedModule := capability.NewAppModule(suite.cdc, *newKeeper, true)
restartedModule.BeginBlock(ctx, abci.RequestBeginBlock{})
suite.Require().True(newKeeper.IsInitialized(ctx), "memstore initialized flag not set")
gasUsed := ctx.BlockGasMeter().GasConsumed()
Expand Down
5 changes: 5 additions & 0 deletions x/capability/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ func (k *Keeper) Seal() {
k.sealed = true
}

// IsSealed returns if the keeper is sealed.
func (k *Keeper) IsSealed() bool {
return k.sealed
}

// InitMemStore will assure that the module store is a memory store (it will panic if it's not)
// and willl initialize it. The function is safe to be called multiple times.
// InitMemStore must be called every time the app starts before the keeper is used (so
Expand Down
Loading

0 comments on commit 17232fa

Please sign in to comment.