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

refactor!: migrate to core appmodule.AppModule extension interfaces #13794

Merged
merged 25 commits into from
Nov 14, 2022

Conversation

aaronc
Copy link
Member

@aaronc aaronc commented Nov 8, 2022

Description

This migrates all modules and the module manager to use the cosmossdk.io/core/appmodule.AppModule interface. It does this in a mostly backwards compatible way. The main breaking change that is required for modules is to implement the tag methods in appmodule.AppModule:

// IsOnePerModuleType implements the depinject.OnePerModuleType interface.
func (am AppModule) IsOnePerModuleType() {}

// IsAppModule implements the appmodule.AppModule interface.
func (am AppModule) IsAppModule() {}

module.AppModule and module.NewManager have been deprecated in favor of appmodule.AppModule and module.NewManagerFromMap.

This refactoring changes the way runtime consumes modules using depinject and now modules should provide
appmodule.AppModule. runtime.AppModuleWrapper and runtime.AppModuleBasicWrapper have been deleted.


Author Checklist

All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.

I have...

  • included the correct type prefix in the PR title
  • added ! to the type prefix if API or client breaking change
  • targeted the correct branch (see PR Targeting)
  • provided a link to the relevant issue or specification
  • followed the guidelines for building modules
  • included the necessary unit and integration tests
  • added a changelog entry to CHANGELOG.md
  • included comments for documenting Go code
  • updated the relevant documentation or specification
  • reviewed "Files changed" and left comments if necessary
  • confirmed all CI checks have passed

Reviewers Checklist

All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.

I have...

  • confirmed the correct type prefix in the PR title
  • confirmed ! in the type prefix if API or client breaking change
  • confirmed all author checklist items have been addressed
  • reviewed state machine logic
  • reviewed API design and naming
  • reviewed documentation is accurate
  • reviewed tests and test coverage
  • manually tested (if applicable)

types/module/module.go Fixed Show fixed Hide fixed
@aaronc aaronc marked this pull request as ready for review November 8, 2022 19:26
@aaronc aaronc requested a review from a team as a code owner November 8, 2022 19:26
Copy link
Member

@tac0turtle tac0turtle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left two comments. Wondering why we need to rename interfaces to legacy?

types/module/module.go Show resolved Hide resolved

// RegisterServices allows a module to register services
// LegacyRegisterServices is the legacy method for modules to register services.
type LegacyRegisterServices interface {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is legacy because of the new core api?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I have the idea to push the new core API version relatively quickly after this. Or we could do the rename to legacy once the core API version is ready. Don't have a strong preference just thought this was clearer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the import will change to use the new api, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well with extension interfaces imports are actually optional, but yes it might

UPGRADING.md Outdated Show resolved Hide resolved
@aaronc
Copy link
Member Author

aaronc commented Nov 11, 2022

I've addressed a bunch of review comments and in particular got rid of AppModuleBasicWrapper. So now modules just need to return an instance of appmodule.AppModule in their Provide function, no wrappers, no module basics. Let me know what you think @AmauryM @julienrbrt @tac0turtle

Comment on lines +91 to +97
for name, mod := range inputs.Modules {
if basicMod, ok := mod.(module.AppModuleBasic); ok {
app.basicManager[name] = basicMod
basicMod.RegisterInterfaces(inputs.InterfaceRegistry)
basicMod.RegisterLegacyAminoCodec(inputs.LegacyAmino)
}
}

Check warning

Code scanning / CodeQL

Iteration over map

Iteration over map may be a possible source of non-determinism
Copy link
Member

@julienrbrt julienrbrt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs lgtm. We backport that to 0.47 right?

Copy link
Contributor

@amaury1093 amaury1093 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@@ -81,15 +81,12 @@ type AppInputs struct {
AppConfig *appv1alpha1.Config
Config *runtimev1alpha1.Module
AppBuilder *AppBuilder
Modules map[string]AppModuleWrapper
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that's a good idea. Totally fine to do in a follow-up too, as this already has approvals. It's not breaking anyways, right?

@aaronc
Copy link
Member Author

aaronc commented Nov 14, 2022

The docs lgtm. We backport that to 0.47 right?

Yes

@aaronc aaronc added the backport/v0.47.x PR scheduled for inclusion in the v0.47's next stable release label Nov 14, 2022
@aaronc aaronc enabled auto-merge (squash) November 14, 2022 15:13
@aaronc
Copy link
Member Author

aaronc commented Nov 14, 2022

Should we be indicating somehow on the extension interfaces (HasServices, HasGenesis, etc.) that these are unstable and that users should expect the core API to change these?

@aaronc
Copy link
Member Author

aaronc commented Nov 14, 2022

Also, most of the mock tests for modules no longer work because we are using extension interfaces which the mock app module doesn't have defined. Any thoughts on what to do? I can either:

  • delete the tests
  • create a mock app module which has all the extension interfaces defined

@aaronc
Copy link
Member Author

aaronc commented Nov 14, 2022

Also, most of the mock tests for modules no longer work because we are using extension interfaces which the mock app module doesn't have defined. Any thoughts on what to do? I can either:

  • delete the tests
  • create a mock app module which has all the extension interfaces defined

I ended up taking the second approach and created a type AppModuleWithAppExtensions that is just used in tests (not exported in the public API). This feels better than deleting tests.

@codecov
Copy link

codecov bot commented Nov 14, 2022

Codecov Report

Merging #13794 (286bd03) into main (14c582f) will decrease coverage by 0.42%.
The diff coverage is 12.93%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main   #13794      +/-   ##
==========================================
- Coverage   56.87%   56.44%   -0.43%     
==========================================
  Files         646      648       +2     
  Lines       55145    56221    +1076     
==========================================
+ Hits        31364    31735     +371     
- Misses      21226    21924     +698     
- Partials     2555     2562       +7     
Impacted Files Coverage Δ
testutil/mock/types_mock_appmodule.go 0.00% <0.00%> (ø)
testutil/mock/types_module_module.go 0.00% <0.00%> (ø)
types/module/simulation.go 0.00% <0.00%> (ø)
x/params/module.go 21.05% <0.00%> (-1.37%) ⬇️
x/genutil/module.go 18.18% <16.66%> (ø)
x/auth/vesting/module.go 10.25% <25.00%> (ø)
x/authz/module/module.go 14.66% <25.00%> (-3.29%) ⬇️
x/upgrade/module.go 28.78% <25.00%> (ø)
x/feegrant/module/module.go 13.15% <33.33%> (-2.23%) ⬇️
types/module/module.go 63.21% <36.84%> (-3.04%) ⬇️
... and 38 more


// BeginBlock mocks base method.
func (m *MockAppModuleWithAllExtensions) BeginBlock(arg0 types0.Context, arg1 types1.RequestBeginBlock) {
m.ctrl.T.Helper()

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// BeginBlock mocks base method.
func (m *MockAppModuleWithAllExtensions) BeginBlock(arg0 types0.Context, arg1 types1.RequestBeginBlock) {
m.ctrl.T.Helper()
m.ctrl.Call(m, "BeginBlock", arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt

// BeginBlock indicates an expected call of BeginBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) BeginBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// BeginBlock indicates an expected call of BeginBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) BeginBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginBlock", reflect.TypeOf((*MockAppModuleWithAllExtensions)(nil).BeginBlock), arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// BeginBlock indicates an expected call of BeginBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) BeginBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginBlock", reflect.TypeOf((*MockAppModuleWithAllExtensions)(nil).BeginBlock), arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt

// EndBlock mocks base method.
func (m *MockAppModuleWithAllExtensions) EndBlock(arg0 types0.Context, arg1 types1.RequestEndBlock) []types1.ValidatorUpdate {
m.ctrl.T.Helper()

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// EndBlock mocks base method.
func (m *MockAppModuleWithAllExtensions) EndBlock(arg0 types0.Context, arg1 types1.RequestEndBlock) []types1.ValidatorUpdate {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EndBlock", arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt

// EndBlock indicates an expected call of EndBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) EndBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// EndBlock indicates an expected call of EndBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) EndBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndBlock", reflect.TypeOf((*MockAppModuleWithAllExtensions)(nil).EndBlock), arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
// EndBlock indicates an expected call of EndBlock.
func (mr *MockAppModuleWithAllExtensionsMockRecorder) EndBlock(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EndBlock", reflect.TypeOf((*MockAppModuleWithAllExtensions)(nil).EndBlock), arg0, arg1)

Check warning

Code scanning / CodeQL

Panic in BeginBock or EndBlock consensus methods

Possible panics in BeginBock- or EndBlock-related consensus methods could cause a chain halt
@aaronc aaronc merged commit ec27c53 into main Nov 14, 2022
@aaronc aaronc deleted the aaronc/appmodule-refactor branch November 14, 2022 21:23
mergify bot pushed a commit that referenced this pull request Nov 14, 2022
tac0turtle pushed a commit that referenced this pull request Nov 15, 2022
…13794) (#13866)

(cherry picked from commit ec27c53)

Co-authored-by: Aaron Craelius <aaron@regen.network>
larry0x pushed a commit to larry0x/cosmos-sdk that referenced this pull request May 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants