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

Demonstrate usage of hooks with depinject #19897

Open
julienrbrt opened this issue Mar 28, 2024 · 0 comments
Open

Demonstrate usage of hooks with depinject #19897

julienrbrt opened this issue Mar 28, 2024 · 0 comments
Labels
T:Docs Changes and features related to documentation. testing-required

Comments

@julienrbrt
Copy link
Member

julienrbrt commented Mar 28, 2024

Currently, x/gov, x/staking, (etc..) and (soon: #19697) x/epochs support hooks. However, we have no demonstration on how to define hooks the depinject way.

The easiest way to do it is to inject the keeper and then call SetHooks on it, like done in app.go (works on a runtime/depinject app too):

cosmos-sdk/simapp/app.go

Lines 397 to 401 in d54e940

app.GovKeeper = *govKeeper.SetHooks(
govtypes.NewMultiGovHooks(
// register the governance hooks
),
)

However, there is wiring in each module to do it the depinject way:

func InvokeSetHooks(keeper *keeper.Keeper, govHooks map[string]govtypes.GovHooksWrapper) error {
if keeper == nil || govHooks == nil {
return nil
}
// Default ordering is lexical by module name.
// Explicit ordering can be added to the module config if required.
modNames := maps.Keys(govHooks)
order := modNames
sort.Strings(order)
var multiHooks govtypes.MultiGovHooks
for _, modName := range order {
hook, ok := govHooks[modName]
if !ok {
return fmt.Errorf("can't find staking hooks for module %s", modName)
}
multiHooks = append(multiHooks, hook)
}
keeper.SetHooks(multiHooks)
return nil
}

func InvokeSetStakingHooks(
config *modulev1.Module,
keeper *keeper.Keeper,
stakingHooks map[string]types.StakingHooksWrapper,
) error {
// all arguments to invokers are optional
if keeper == nil || config == nil {
return nil
}
modNames := maps.Keys(stakingHooks)
order := config.HooksOrder
if len(order) == 0 {
order = modNames
sort.Strings(order)
}
if len(order) != len(modNames) {
return fmt.Errorf("len(hooks_order: %v) != len(hooks modules: %v)", order, modNames)
}
if len(modNames) == 0 {
return nil
}
var multiHooks types.MultiStakingHooks
for _, modName := range order {
hook, ok := stakingHooks[modName]
if !ok {
return fmt.Errorf("can't find staking hooks for module %s", modName)
}
multiHooks = append(multiHooks, hook)
}
keeper.SetHooks(multiHooks)
return nil
}

Basically, a module should provide / output its hooks' definition (IsOnePerModuleType) and depinject will create a map of all defined hooks.

We should demonstrate how a module can provide a hook. Let's use the testing counter module for that and demonstrate a hook definition.

@julienrbrt julienrbrt added T:Docs Changes and features related to documentation. testing-required labels Mar 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T:Docs Changes and features related to documentation. testing-required
Projects
Status: 📋 Backlog
Development

No branches or pull requests

1 participant