Skip to content

Commit

Permalink
feat(x/auth): app wiring setup (#12019)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronc authored May 27, 2022
1 parent 81ee241 commit dfe29ee
Show file tree
Hide file tree
Showing 11 changed files with 2,227 additions and 74 deletions.
777 changes: 741 additions & 36 deletions api/cosmos/app/runtime/v1alpha1/module.pulsar.go

Large diffs are not rendered by default.

1,342 changes: 1,342 additions & 0 deletions api/cosmos/auth/module/v1/module.pulsar.go

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions proto/cosmos/app/runtime/v1alpha1/module.proto
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,18 @@ message Module {
// If this is left empty, the init_genesis order will be used for export genesis
// if it is specified.
repeated string export_genesis = 5;

// override_store_keys is an optional list of overrides for the module store keys
// to be used in keeper construction.
repeated StoreKeyConfig override_store_keys = 6;
}

// StoreKeyConfig may be supplied to override the default module store key, which
// is the module name.
message StoreKeyConfig {
// name of the module to override the store key of
string module_name = 1;

// the kv store key to use instead of the module name.
string kv_store_key = 2;
}
28 changes: 28 additions & 0 deletions proto/cosmos/auth/module/v1/module.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
syntax = "proto3";

package cosmos.auth.module.v1;

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

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

// bech32_prefix is the bech32 account prefix for the app.
string bech32_prefix = 1;

// module_account_permissions are module account permissions.
repeated ModuleAccountPermission module_account_permissions = 2;
}

// ModuleAccountPermission represents permissions for a module account.
message ModuleAccountPermission {
// account is the name of the module.
string account = 1;

// permissions are the permissions this module has. Currently recognized
// values are minter, burner and staking.
repeated string permissions = 2;
}
14 changes: 7 additions & 7 deletions runtime/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"encoding/json"
"fmt"

"github.com/gogo/protobuf/grpc"
abci "github.com/tendermint/tendermint/abci/types"
"golang.org/x/exp/slices"

Expand Down Expand Up @@ -36,6 +35,7 @@ import (
type App struct {
*baseapp.BaseApp
ModuleManager *module.Manager
configurator module.Configurator
config *runtimev1alpha1.Module
storeKeys []storetypes.StoreKey
interfaceRegistry codectypes.InterfaceRegistry
Expand All @@ -45,8 +45,6 @@ type App struct {
beginBlockers []func(sdk.Context, abci.RequestBeginBlock)
endBlockers []func(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate
baseAppOptions []BaseAppOption

msgServiceRegistrar grpc.Server
}

// RegisterModules registers the provided modules with the module manager and
Expand Down Expand Up @@ -74,10 +72,8 @@ func (a *App) RegisterModules(modules ...module.AppModule) error {

// Load finishes all initialization operations and loads the app.
func (a *App) Load(loadLatest bool) error {
if a.msgServiceRegistrar != nil {
configurator := module.NewConfigurator(a.cdc, a.msgServiceRegistrar, a.GRPCQueryRouter())
a.ModuleManager.RegisterServices(configurator)
}
a.configurator = module.NewConfigurator(a.cdc, a.MsgServiceRouter(), a.GRPCQueryRouter())
a.ModuleManager.RegisterServices(a.configurator)

if len(a.config.InitGenesis) != 0 {
a.ModuleManager.SetOrderInitGenesis(a.config.InitGenesis...)
Expand Down Expand Up @@ -156,6 +152,10 @@ func (a *App) RegisterTendermintService(clientCtx client.Context) {
)
}

func (a *App) Configurator() module.Configurator {
return a.configurator
}

// UnsafeFindStoreKey FindStoreKey fetches a registered StoreKey from the App in linear time.
//
// NOTE: This should only be used in testing.
Expand Down
37 changes: 25 additions & 12 deletions runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ package runtime
import (
"fmt"

"github.com/gogo/protobuf/grpc"

runtimev1alpha1 "cosmossdk.io/api/cosmos/app/runtime/v1alpha1"
"cosmossdk.io/core/appmodule"
"github.com/cosmos/cosmos-sdk/depinject"

"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/depinject"
"github.com/cosmos/cosmos-sdk/std"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/types/module"
Expand Down Expand Up @@ -75,11 +72,10 @@ func provideCodecs(moduleBasics map[string]AppModuleBasicWrapper) (
type appInputs struct {
depinject.In

Config *runtimev1alpha1.Module
App appWrapper
Modules map[string]AppModuleWrapper
BaseAppOptions []BaseAppOption
MsgServiceRegistrar grpc.Server `optional:"true"`
Config *runtimev1alpha1.Module
App appWrapper
Modules map[string]AppModuleWrapper
BaseAppOptions []BaseAppOption
}

func provideAppBuilder(inputs appInputs) *AppBuilder {
Expand All @@ -91,16 +87,33 @@ func provideAppBuilder(inputs appInputs) *AppBuilder {
app.baseAppOptions = inputs.BaseAppOptions
app.config = inputs.Config
app.ModuleManager = mm
app.msgServiceRegistrar = inputs.MsgServiceRegistrar
return &AppBuilder{app: app}
}

func registerStoreKey(wrapper appWrapper, key storetypes.StoreKey) {
wrapper.storeKeys = append(wrapper.storeKeys, key)
}

func provideKVStoreKey(key depinject.ModuleKey, app appWrapper) *storetypes.KVStoreKey {
storeKey := storetypes.NewKVStoreKey(key.Name())
func storeKeyOverride(config *runtimev1alpha1.Module, moduleName string) *runtimev1alpha1.StoreKeyConfig {
for _, cfg := range config.OverrideStoreKeys {
if cfg.ModuleName == moduleName {
return cfg
}
}
return nil
}

func provideKVStoreKey(config *runtimev1alpha1.Module, key depinject.ModuleKey, app appWrapper) *storetypes.KVStoreKey {
override := storeKeyOverride(config, key.Name())

var storeKeyName string
if override != nil {
storeKeyName = override.KvStoreKey
} else {
storeKeyName = key.Name()
}

storeKey := storetypes.NewKVStoreKey(storeKeyName)
registerStoreKey(app, storeKey)
return storeKey
}
Expand Down
16 changes: 5 additions & 11 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,6 @@ type SimApp struct {

// simulation manager
sm *module.SimulationManager

// module configurator
configurator module.Configurator
}

func init() {
Expand All @@ -213,6 +210,7 @@ func NewSimApp(
) *SimApp {
var appBuilder *runtime.AppBuilder
var paramsKeeper paramskeeper.Keeper
var accountKeeper authkeeper.AccountKeeper
var appCodec codec.Codec
var legacyAmino *codec.LegacyAmino
var interfaceRegistry codectypes.InterfaceRegistry
Expand All @@ -222,6 +220,7 @@ func NewSimApp(
&appCodec,
&legacyAmino,
&interfaceRegistry,
&accountKeeper,
)
if err != nil {
panic(err)
Expand All @@ -230,7 +229,7 @@ func NewSimApp(
runtimeApp := appBuilder.Build(logger, db, traceStore, baseAppOptions...)

keys := sdk.NewKVStoreKeys(
authtypes.StoreKey, banktypes.StoreKey, stakingtypes.StoreKey,
banktypes.StoreKey, stakingtypes.StoreKey,
minttypes.StoreKey, distrtypes.StoreKey, slashingtypes.StoreKey,
govtypes.StoreKey, upgradetypes.StoreKey, feegrant.StoreKey,
evidencetypes.StoreKey, capabilitytypes.StoreKey,
Expand Down Expand Up @@ -259,15 +258,14 @@ func NewSimApp(
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()

// add keepers
app.AccountKeeper = authkeeper.NewAccountKeeper(
appCodec, keys[authtypes.StoreKey], app.GetSubspace(authtypes.ModuleName), authtypes.ProtoBaseAccount, maccPerms, sdk.Bech32MainPrefix,
)
app.BankKeeper = bankkeeper.NewBaseKeeper(
appCodec, keys[banktypes.StoreKey], app.AccountKeeper, app.GetSubspace(banktypes.ModuleName), app.ModuleAccountAddrs(),
)
Expand Down Expand Up @@ -355,7 +353,6 @@ func NewSimApp(
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),
Expand Down Expand Up @@ -395,8 +392,6 @@ func NewSimApp(

app.ModuleManager.RegisterInvariants(&app.CrisisKeeper)
app.ModuleManager.RegisterRoutes(app.Router(), app.QueryRouter(), encodingConfig.Amino)
app.configurator = module.NewConfigurator(app.appCodec, app.MsgServiceRouter(), app.GRPCQueryRouter())
app.ModuleManager.RegisterServices(app.configurator)

// add test gRPC service for testing gRPC queries in isolation
testdata_pulsar.RegisterQueryServer(app.GRPCQueryRouter(), testdata_pulsar.QueryImpl{})
Expand Down Expand Up @@ -617,7 +612,6 @@ func GetMaccPerms() map[string][]string {

// initParamsKeeper init params keeper and its subspaces
func initParamsKeeper(paramsKeeper paramskeeper.Keeper) {
paramsKeeper.Subspace(authtypes.ModuleName)
paramsKeeper.Subspace(banktypes.ModuleName)
paramsKeeper.Subspace(stakingtypes.ModuleName)
paramsKeeper.Subspace(minttypes.ModuleName)
Expand Down
21 changes: 21 additions & 0 deletions simapp/app.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,27 @@ modules:
feegrant, nft, group,
params, upgrade, vesting ]

override_store_keys:
- module_name: auth
kv_store_key: acc

- name: auth
config:
"@type": cosmos.auth.module.v1.Module
bech32_prefix: cosmos
module_account_permissions:
- account: fee_collector
- account: distribution
- account: mint
permissions: [ minter ]
- account: bonded_tokens_pool
permissions: [ burner, staking ]
- account: not_bonded_tokens_pool
permissions: [ burner, staking ]
- account: gov
permissions: [ burner ]
- account: nft

- name: params
config:
"@type": cosmos.params.module.v1.Module
10 changes: 5 additions & 5 deletions simapp/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestRunMigrations(t *testing.T) {
bApp.SetCommitMultiStoreTracer(nil)
bApp.SetInterfaceRegistry(encCfg.InterfaceRegistry)
app.BaseApp = bApp
app.configurator = module.NewConfigurator(app.appCodec, bApp.MsgServiceRouter(), app.GRPCQueryRouter())
configurator := module.NewConfigurator(app.appCodec, bApp.MsgServiceRouter(), app.GRPCQueryRouter())

// We register all modules on the Configurator, except x/bank. x/bank will
// serve as the test subject on which we run the migration tests.
Expand All @@ -94,7 +94,7 @@ func TestRunMigrations(t *testing.T) {
continue
}

module.RegisterServices(app.configurator)
module.RegisterServices(configurator)
}

// Initialize the chain
Expand Down Expand Up @@ -150,7 +150,7 @@ func TestRunMigrations(t *testing.T) {

if tc.moduleName != "" {
// Register migration for module from version `fromVersion` to `fromVersion+1`.
err = app.configurator.RegisterMigration(tc.moduleName, tc.fromVersion, func(sdk.Context) error {
err = configurator.RegisterMigration(tc.moduleName, tc.fromVersion, func(sdk.Context) error {
called++

return nil
Expand All @@ -168,7 +168,7 @@ func TestRunMigrations(t *testing.T) {
// version for bank as 1, and for all other modules, we put as
// their latest ConsensusVersion.
_, err = app.ModuleManager.RunMigrations(
app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}), app.configurator,
app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()}), configurator,
module.VersionMap{
"bank": 1,
"auth": auth.AppModule{}.ConsensusVersion(),
Expand Down Expand Up @@ -221,7 +221,7 @@ func TestInitGenesisOnMigration(t *testing.T) {

// Run migrations only for "mock" module. We exclude it from
// the VersionMap to simulate upgrading with a new module.
_, err := app.ModuleManager.RunMigrations(ctx, app.configurator,
_, err := app.ModuleManager.RunMigrations(ctx, app.Configurator(),
module.VersionMap{
"bank": bank.AppModule{}.ConsensusVersion(),
"auth": auth.AppModule{}.ConsensusVersion(),
Expand Down
2 changes: 1 addition & 1 deletion simapp/upgrades.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (app SimApp) RegisterUpgradeHandlers() {
"genutil": 1,
}

return app.ModuleManager.RunMigrations(ctx, app.configurator, fromVM)
return app.ModuleManager.RunMigrations(ctx, app.Configurator(), fromVM)
})

upgradeInfo, err := app.UpgradeKeeper.ReadUpgradeInfoFromDisk()
Expand Down
40 changes: 38 additions & 2 deletions x/auth/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ import (
"fmt"
"math/rand"

"github.com/grpc-ecosystem/grpc-gateway/runtime"
gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime"

"github.com/spf13/cobra"
abci "github.com/tendermint/tendermint/abci/types"

"cosmossdk.io/core/appmodule"
modulev1 "cosmossdk.io/api/cosmos/auth/module/v1"
"github.com/cosmos/cosmos-sdk/runtime"
store "github.com/cosmos/cosmos-sdk/store/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
Expand Down Expand Up @@ -59,7 +65,7 @@ func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncod
}

// RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the auth module.
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux) {
func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *gwruntime.ServeMux) {
if err := types.RegisterQueryHandlerClient(context.Background(), mux, types.NewQueryClient(clientCtx)); err != nil {
panic(err)
}
Expand Down Expand Up @@ -185,3 +191,33 @@ func (am AppModule) RegisterStoreDecoder(sdr sdk.StoreDecoderRegistry) {
func (AppModule) WeightedOperations(_ 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{})
}

func provideModule(
config *modulev1.Module,
key *store.KVStoreKey,
cdc codec.Codec,
subspace paramtypes.Subspace) (keeper.AccountKeeper, runtime.AppModuleWrapper) {

maccPerms := map[string][]string{}
for _, permission := range config.ModuleAccountPermissions {
maccPerms[permission.Account] = permission.Permissions
}

k := keeper.NewAccountKeeper(cdc, key, subspace, types.ProtoBaseAccount, maccPerms, config.Bech32Prefix)
m := NewAppModule(cdc, k, simulation.RandomGenesisAccounts)
return k, runtime.WrapAppModule(m)
}

0 comments on commit dfe29ee

Please sign in to comment.