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: introduce PreBlock #17421

Merged
merged 42 commits into from
Sep 13, 2023
Merged

feat: introduce PreBlock #17421

merged 42 commits into from
Sep 13, 2023

Conversation

mmsqe
Copy link
Contributor

@mmsqe mmsqe commented Aug 17, 2023

  1. to runs before begin blocker, and be more generic than hardcode with migration
  2. allowed to modify consensus parameters and the changes are visible to the following state machine logics
  3. add missing refresh for finalizeBlockState.ctx, since only ctx within beginBlock scope was changed, it did not update the ConsensusParams of finalizeBlockState.ctx which is used in endBlock and now it does
  4. add ConsensusParamsChanged check to avoid refreshing ConsensusParams of ctx every time

Description

Updates #16583

Context

The Original Problem

When upgrading to sdk 0.47, the storage format for consensus parameters changed, but in the migration block, ctx.ConsensusParams() is always nil, because it fails to load the old format using new code, it's supposed to be migrated by the x/upgrade module first, but unfortunately, the migration happens in BeginBlocker handler, which runs after the ctx is initialized.
When we try to solve this, we find the x/upgrade module can't modify the context to make the consensus parameters visible for the other modules, the context is passed by value, and sdk team want to keep it that way, that's good for isolations between modules.
The first alternative solution introduced a MigrateModuleManager, which only includes the x/upgrade module right now, and baseapp will run their BeginBlockers before the other modules, and reload context's consensus parameters in between, but I think it's too hacky, and suggested this new lifecycle method.

PreBlocker

There are two semantics around the new lifecycle method:

  • It runs before the BeginBlocker of all modules
  • It can modify consensus parameters in storage, and signal the caller through the return value.

When it returns ConsensusParamsChanged=true, the caller must refresh the consensus parameter in the deliver context:

app.deliverState.ctx = app.deliverState.ctx.WithConsensusParams(app.GetConsensusParams())

The new ctx must be passed to all the other lifecycle methods.


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
  • run make lint and make test
  • 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 Dismissed Show dismissed Hide dismissed
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.

Not super a fan personally of this new notion of pre-begin blocker.

With PreCommitter, PrepareCheckStaters, I feel like it makes the module API more complicated.

What was the issue with the previous implementation? And why does it need to be generalized? What kind of module other than upgrade could take advantage of this?

CHANGELOG.md Outdated
@@ -55,6 +55,8 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (version) [#17096](https://github.com/cosmos/cosmos-sdk/pull/17096) Improve `getSDKVersion()` to handle module replacements
* (x/staking) [#17164](https://github.com/cosmos/cosmos-sdk/pull/17164) Add `BondedTokensAndPubKeyByConsAddr` to the keeper to enable vote extension verification.
* (x/genutil) [#17296](https://github.com/cosmos/cosmos-sdk/pull/17296) Add `MigrateHandler` to allow reuse migrate genesis related function.
* (types) [#17421](https://github.com/cosmos/cosmos-sdk/pull/17421) Replace `RunMigrationBeginBlock` with `PreBeginBlock`, which runs before begin blocker other modules, and allows to modify consensus parameters, and the changes are visible to the following state machine logics.
Copy link
Member

@julienrbrt julienrbrt Aug 17, 2023

Choose a reason for hiding this comment

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

It was never released so no changelog needed, best to edit the other changelog and add this PR number next to it.

@@ -222,6 +222,11 @@ type HasConsensusVersion interface {
ConsensusVersion() uint64
}

type PreBeginBlockAppModule interface {
AppModule
Copy link
Member

@julienrbrt julienrbrt Aug 17, 2023

Choose a reason for hiding this comment

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

These should be on core/appmodule and named Has<...>. We shouldn't introduce module related interface in types/module unless we need an sdk dependency.

@yihuang
Copy link
Collaborator

yihuang commented Aug 17, 2023

Not super a fan personally of this new notion of pre-begin blocker.

With PreCommitter, PrepareCheckStaters, I feel like it makes the module API more complicated.

What was the issue with the previous implementation? And why does it need to be generalized? What kind of module other than upgrade could take advantage of this?

the main issue with the previous implementation is it treat some begin blockers different from the other begin blockers, but they are all named as BeginBlock, that could be confusing.

baseapp/baseapp.go Outdated Show resolved Hide resolved
* to runs before begin blocker, and be more generic than hardcode with migration
* allowed to modify consensus parameters and the changes are visible to the following state machine logics
@mmsqe mmsqe force-pushed the pre-begin branch 3 times, most recently from 25002c4 to 8c0cccd Compare August 17, 2023 12:05
@mmsqe mmsqe marked this pull request as ready for review August 17, 2023 12:48
@mmsqe mmsqe requested a review from a team as a code owner August 17, 2023 12:48
@github-prbot github-prbot requested review from a team, facundomedica and samricotta and removed request for a team August 17, 2023 12:48
@julienrbrt julienrbrt self-assigned this Aug 17, 2023
x/upgrade/abci.go Outdated Show resolved Hide resolved
@mmsqe mmsqe changed the title refactor: replace RunMigrationBeginBlock with PreBeginBlock refactor: replace RunMigrationBeginBlock with PreBlock Aug 17, 2023
runtime/app.go Outdated Show resolved Hide resolved
@tac0turtle
Copy link
Member

@mmsqe could you resolve conflicts? lets see about getting this merged

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.

LGTM, we can do it after the fact, a short adr would be good on this feature so we have it documented

x/upgrade/module.go Outdated Show resolved Hide resolved
baseapp/baseapp.go Outdated Show resolved Hide resolved
Comment on lines 736 to +742
}
}

if err := app.preBlock(); err != nil {
return nil, err
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Change potentially affects state.

Call sequence:

(*github.com/cosmos/cosmos-sdk/baseapp.BaseApp).FinalizeBlock (baseapp/abci.go:669)

Comment on lines +682 to +688
ctx = ctx.WithConsensusParams(app.GetConsensusParams(ctx))
// GasMeter must be set after we get a context with updated consensus params.
gasMeter := app.getBlockGasMeter(ctx)
ctx = ctx.WithBlockGasMeter(gasMeter)
app.finalizeBlockState.ctx = ctx
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Change potentially affects state.

Call sequence:

(*github.com/cosmos/cosmos-sdk/baseapp.BaseApp).beginBlock (baseapp/baseapp.go:685)
(*github.com/cosmos/cosmos-sdk/baseapp.BaseApp).FinalizeBlock (baseapp/baseapp.go:669)

auto-merge was automatically disabled September 13, 2023 11:50

Head branch was pushed to by a user without write access

@julienrbrt julienrbrt added this pull request to the merge queue Sep 13, 2023
Merged via the queue into cosmos:main with commit 4eb0185 Sep 13, 2023
39 of 45 checks passed
mergify bot pushed a commit that referenced this pull request Sep 13, 2023
(cherry picked from commit 4eb0185)

# Conflicts:
#	CHANGELOG.md
#	UPGRADING.md
#	docs/docs/build/building-apps/03-app-upgrade.md
#	docs/docs/build/building-modules/01-module-manager.md
#	docs/docs/develop/advanced/00-baseapp.md
#	runtime/builder.go
#	simapp/go.mod
#	simapp/go.sum
#	simapp/gomod2nix.toml
#	tests/go.mod
#	tests/go.sum
#	tests/starship/tests/go.mod
#	tests/starship/tests/go.sum
#	testutil/mock/types_mock_appmodule.go
#	types/module/module.go
#	types/module/module_test.go
#	x/feegrant/go.mod
#	x/upgrade/abci.go
#	x/upgrade/abci_test.go
#	x/upgrade/go.mod
#	x/upgrade/go.sum
@julienrbrt
Copy link
Member

@mmsqe, are you up to submit this PR https://github.com/mmsqe/cosmos-sdk/pull/2/files now to main?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants