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

fix: Add MigrationModuleManager to handle migration of upgrade module before other modules #16583

Merged
merged 35 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
1e55c09
add WithConsensusParamsGetter for manager
mmsqe Jun 15, 2023
5d513a3
test WithConsensusParamsGetter
mmsqe Jun 16, 2023
3fcd4d6
test continuously call BeginBlock
mmsqe Jun 16, 2023
34d47d1
add doc
mmsqe Jun 16, 2023
c21cff7
rm module name check
mmsqe Jun 16, 2023
ea9e96a
add change log
mmsqe Jun 16, 2023
721fb8b
Update CHANGELOG.md
mmsqe Jun 16, 2023
3158f6a
fix interface
mmsqe Jun 16, 2023
e54fc1a
fix lint
mmsqe Jun 16, 2023
81038ec
Apply suggestions from code review
mmsqe Jun 20, 2023
36a3944
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Jun 20, 2023
5e43e65
cleanup doc
mmsqe Jun 16, 2023
9c3a25b
fix resolve
mmsqe Jun 20, 2023
5bca160
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Jun 26, 2023
9f6994d
fix lint
mmsqe Jun 26, 2023
591d7cf
add ck
mmsqe Jun 27, 2023
e3f80d6
Revert "add ck"
mmsqe Jun 27, 2023
26e9624
add ConsensusParamsGetter interface
mmsqe Jun 27, 2023
6e50d86
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Jul 17, 2023
42fc450
fix doc
mmsqe Jul 18, 2023
59f4bef
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Aug 9, 2023
120cdae
handle upgrade 1st
mmsqe Aug 9, 2023
74746c9
Update x/upgrade/module.go
mmsqe Aug 10, 2023
7c812be
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Aug 10, 2023
bbf4eef
fix doc
mmsqe Aug 10, 2023
ca99e59
replace WithConsensusParamsGetter with MigrationModuleManager
mmsqe Aug 10, 2023
86bc9c0
fix test
mmsqe Aug 10, 2023
1a1b3ce
Apply suggestions from code review
mmsqe Aug 10, 2023
5400774
check nil
mmsqe Aug 11, 2023
2b56da6
update doc
mmsqe Aug 11, 2023
95c6ed9
add test
mmsqe Aug 11, 2023
08a9279
Merge remote-tracking branch 'origin/main' into fix_cp
mmsqe Aug 11, 2023
6ceebbf
update doc
mmsqe Aug 11, 2023
71ea378
Apply suggestions from code review
mmsqe Aug 11, 2023
ff7f08d
Merge branch 'main' into fix_cp
julienrbrt Aug 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

* [#16547](https://github.com/cosmos/cosmos-sdk/pull/16547) Ensure a transaction's gas limit cannot exceed the block gas limit.
* (x/auth/types) [#16554](https://github.com/cosmos/cosmos-sdk/pull/16554) `ModuleAccount.Validate` now reports a nil `.BaseAccount` instead of panicking.
* (migrations) [#16583](https://github.com/cosmos/cosmos-sdk/pull/16583) Add `WithConsensusParamsGetter` to allow other modules to access updated context with consensus parameters within the same block that executes migration.
julienrbrt marked this conversation as resolved.
Show resolved Hide resolved
* (baseapp) [#16613](https://github.com/cosmos/cosmos-sdk/pull/16613) Ensure each message in a transaction has a registered handler, otherwise `CheckTx` will fail.

## [v0.50.0-alpha.0](https://github.com/cosmos/cosmos-sdk/releases/tag/v0.50.0-alpha.0) - 2023-06-07
Expand Down
2 changes: 1 addition & 1 deletion runtime/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func SetupAppBuilder(inputs AppInputs) {
app.config = inputs.Config
app.appConfig = inputs.AppConfig
app.logger = inputs.Logger
app.ModuleManager = module.NewManagerFromMap(inputs.Modules)
app.ModuleManager = module.NewManagerFromMap(inputs.Modules).WithConsensusParamsGetter(app)

for name, mod := range inputs.Modules {
if customBasicMod, ok := inputs.CustomModuleBasics[name]; ok {
Expand Down
2 changes: 1 addition & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func NewSimApp(
logger,
)
app.StakingKeeper = stakingkeeper.NewKeeper(
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
appCodec, runtime.NewKVStoreService(keys[stakingtypes.StoreKey]), app.AccountKeeper, app.BankKeeper, app.ConsensusParamsKeeper, authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
app.MintKeeper = mintkeeper.NewKeeper(appCodec, runtime.NewKVStoreService(keys[minttypes.StoreKey]), app.StakingKeeper, app.AccountKeeper, app.BankKeeper, authtypes.FeeCollectorName, authtypes.NewModuleAddress(govtypes.ModuleName).String())

Expand Down
24 changes: 24 additions & 0 deletions types/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (
"sort"

abci "github.com/cometbft/cometbft/abci/types"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/spf13/cobra"
"golang.org/x/exp/maps"
Expand Down Expand Up @@ -261,6 +262,11 @@ func (GenesisOnlyAppModule) EndBlock(sdk.Context) ([]abci.ValidatorUpdate, error
return []abci.ValidatorUpdate{}, nil
}

// ConsensusParamsGetter is an interface to retrieve consensus parameters for a given context.
type ConsensusParamsGetter interface {
GetConsensusParams(ctx sdk.Context) tmproto.ConsensusParams
Copy link
Contributor

Choose a reason for hiding this comment

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

what if we just return an any here and then type cast? Then we can avoid the CometBFT dependency.

Copy link
Contributor Author

@mmsqe mmsqe Jun 27, 2023

Choose a reason for hiding this comment

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

since need use as cp := getter.GetConsensusParams(ctx).(tmproto.ConsensusParams), we can't use any for WithConsensusParams, or can we add a separate package to avoid import cometbft type directly

}

// Manager defines a module manager that provides the high level utility for managing and executing
// operations for a group of modules
type Manager struct {
Expand All @@ -272,6 +278,7 @@ type Manager struct {
OrderPrepareCheckStaters []string
OrderPrecommiters []string
OrderMigrations []string
consensusParamsGetter ConsensusParamsGetter
}

// NewManager creates a new Manager object.
Expand Down Expand Up @@ -318,6 +325,12 @@ func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager {
}
}

// WithConsensusParamsGetter sets ConsensusParamsGetter for Manager.
func (m *Manager) WithConsensusParamsGetter(g ConsensusParamsGetter) *Manager {
m.consensusParamsGetter = g
return m
}

// SetOrderInitGenesis sets the order of init genesis calls
func (m *Manager) SetOrderInitGenesis(moduleNames ...string) {
m.assertNoForgottenModules("SetOrderInitGenesis", moduleNames, func(moduleName string) bool {
Expand Down Expand Up @@ -700,6 +713,17 @@ func (m *Manager) BeginBlock(ctx sdk.Context) (sdk.BeginBlock, error) {
if err != nil {
return sdk.BeginBlock{}, err
}
if m.consensusParamsGetter != nil {
cp := ctx.ConsensusParams()
// Manager skips this step if Block is non-nil since upgrade module is expected to set this params
// and consensus parameters should not be overwritten.
if cp.Block == nil {
cp = m.consensusParamsGetter.GetConsensusParams(ctx)
Fixed Show fixed Hide fixed
if cp.Block != nil {
ctx = ctx.WithConsensusParams(cp)
}
}
}
}
}

Expand Down
65 changes: 65 additions & 0 deletions types/module/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"io"
"reflect"
"testing"

abci "github.com/cometbft/cometbft/abci/types"
Expand Down Expand Up @@ -482,6 +483,70 @@ func TestCoreAPIManager_BeginBlock(t *testing.T) {
require.EqualError(t, err, "some error")
}

type MockConsensusParamGetter struct {
ctrl *gomock.Controller
recorder *MockConsensusParamGetterRecorder
}

type MockConsensusParamGetterRecorder struct {
mock *MockConsensusParamGetter
}

func NewMockConsensusParamGetter(ctrl *gomock.Controller) *MockConsensusParamGetter {
mock := &MockConsensusParamGetter{ctrl: ctrl}
mock.recorder = &MockConsensusParamGetterRecorder{mock}
return mock
}

func (m *MockConsensusParamGetter) EXPECT() *MockConsensusParamGetterRecorder {
return m.recorder
}

func (m *MockConsensusParamGetter) GetConsensusParams(arg0 sdk.Context) cmtproto.ConsensusParams {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetConsensusParams", arg0)
ret0, _ := ret[0].(cmtproto.ConsensusParams)
return ret0
}

func (mr *MockConsensusParamGetterRecorder) GetConsensusParams(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetConsensusParams", reflect.TypeOf((*MockConsensusParamGetter)(nil).GetConsensusParams), arg0)
}

func TestManager_BeginBlock_WithConsensusParamsGetter(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)

mockUpgradeModule := mock.NewMockCoreAppModule(mockCtrl)
mockParamsGetter := NewMockConsensusParamGetter(mockCtrl)

// Create a Manager with the mock consensusParamsGetter and an upgrade module
m := module.NewManagerFromMap(map[string]appmodule.AppModule{
"upgrade": mockUpgradeModule,
}).WithConsensusParamsGetter(mockParamsGetter)

// Create a context with a nil consensus params object and an empty event manager
ctx := sdk.Context{}

mockUpgradeModule.EXPECT().BeginBlock(gomock.Any()).Times(1).Return(nil)
mockParamsGetter.EXPECT().GetConsensusParams(gomock.Any()).Times(1).Return(cmtproto.ConsensusParams{
Block: &cmtproto.BlockParams{MaxBytes: 1000},
})
_, err := m.BeginBlock(ctx)
require.NoError(t, err)

// Create a context with a consensus params object and an empty event manager
ctx = sdk.Context{}.WithConsensusParams(cmtproto.ConsensusParams{
Block: &cmtproto.BlockParams{MaxBytes: 1000},
})

mockUpgradeModule.EXPECT().BeginBlock(gomock.Any()).Times(1).Return(nil)
mockParamsGetter.EXPECT().GetConsensusParams(gomock.Any()).Times(0)
_, err = m.BeginBlock(ctx)
require.NoError(t, err)
}

func TestCoreAPIManager_EndBlock(t *testing.T) {
mockCtrl := gomock.NewController(t)
t.Cleanup(mockCtrl.Finish)
Expand Down
9 changes: 9 additions & 0 deletions x/consensus/types/expected_keepers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package types

import (
context "context"
)

type ConsensusKeeper interface {
Params(ctx context.Context, _ *QueryParamsRequest) (*QueryParamsResponse, error)
}
28 changes: 16 additions & 12 deletions x/staking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
consensustypes "github.com/cosmos/cosmos-sdk/x/consensus/types"
"github.com/cosmos/cosmos-sdk/x/staking/types"
)

Expand All @@ -23,12 +24,13 @@ var _ types.DelegationSet = Keeper{}

// Keeper of the x/staking store
type Keeper struct {
storeService storetypes.KVStoreService
cdc codec.BinaryCodec
authKeeper types.AccountKeeper
bankKeeper types.BankKeeper
hooks types.StakingHooks
authority string
storeService storetypes.KVStoreService
cdc codec.BinaryCodec
authKeeper types.AccountKeeper
bankKeeper types.BankKeeper
hooks types.StakingHooks
consensusKeeper consensustypes.ConsensusKeeper
authority string
}

// NewKeeper creates a new staking Keeper instance
Expand All @@ -37,6 +39,7 @@ func NewKeeper(
storeService storetypes.KVStoreService,
ak types.AccountKeeper,
bk types.BankKeeper,
ck consensustypes.ConsensusKeeper,
authority string,
) *Keeper {
// ensure bonded and not bonded module accounts are set
Expand All @@ -54,12 +57,13 @@ func NewKeeper(
}

return &Keeper{
storeService: storeService,
cdc: cdc,
authKeeper: ak,
bankKeeper: bk,
hooks: nil,
authority: authority,
storeService: storeService,
cdc: cdc,
authKeeper: ak,
bankKeeper: bk,
consensusKeeper: ck,
hooks: nil,
authority: authority,
}
}

Expand Down
3 changes: 3 additions & 0 deletions x/staking/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,14 @@ func (s *KeeperTestSuite) SetupTest() {

bankKeeper := stakingtestutil.NewMockBankKeeper(ctrl)

consensusKeeper := stakingtestutil.NewMockConsensusKeeper(ctrl)

keeper := stakingkeeper.NewKeeper(
encCfg.Codec,
storeService,
accountKeeper,
bankKeeper,
consensusKeeper,
authtypes.NewModuleAddress(stakingtypes.GovModuleName).String(),
)
require.NoError(keeper.SetParams(ctx, stakingtypes.DefaultParams()))
Expand Down
7 changes: 7 additions & 0 deletions x/staking/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ func (k msgServer) CreateValidator(ctx context.Context, msg *types.MsgCreateVali

sdkCtx := sdk.UnwrapSDKContext(ctx)
cp := sdkCtx.ConsensusParams()
if cp.Block == nil {
res, err := k.consensusKeeper.Params(ctx, nil)
if err != nil {
return nil, err
}
cp = *res.Params
}
if cp.Validator != nil {
pkType := pk.Type()
hasKeyType := false
Expand Down
13 changes: 8 additions & 5 deletions x/staking/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/cosmos/cosmos-sdk/types/module"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper"
"github.com/cosmos/cosmos-sdk/x/staking/client/cli"
"github.com/cosmos/cosmos-sdk/x/staking/exported"
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
Expand Down Expand Up @@ -209,11 +210,12 @@ func init() {
type ModuleInputs struct {
depinject.In

Config *modulev1.Module
AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
Cdc codec.Codec
StoreService store.KVStoreService
Config *modulev1.Module
AccountKeeper types.AccountKeeper
BankKeeper types.BankKeeper
consensusKeeper consensusparamkeeper.Keeper
Cdc codec.Codec
StoreService store.KVStoreService

// LegacySubspace is used solely for migration of x/params managed parameters
LegacySubspace exported.Subspace `optional:"true"`
Expand All @@ -239,6 +241,7 @@ func ProvideModule(in ModuleInputs) ModuleOutputs {
in.StoreService,
in.AccountKeeper,
in.BankKeeper,
in.consensusKeeper,
authority.String(),
)
m := NewAppModule(in.Cdc, k, in.AccountKeeper, in.BankKeeper, in.LegacySubspace)
Expand Down
38 changes: 38 additions & 0 deletions x/staking/testutil/expected_keepers_mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.