From cda4b81fba8b7babb2c3b2b34fd14ff8dbb509d4 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Tue, 31 Jan 2023 17:20:00 -0500 Subject: [PATCH 01/16] Add Commit callback --- baseapp/abci.go | 4 ++++ baseapp/baseapp.go | 1 + baseapp/options.go | 8 ++++++++ telemetry/wrapper.go | 1 + types/abci.go | 4 ++++ types/module/module.go | 24 ++++++++++++++++++++++++ 6 files changed, 42 insertions(+) diff --git a/baseapp/abci.go b/baseapp/abci.go index dc89c364c12..a7b185b6dee 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -488,6 +488,10 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // empty/reset the deliver state app.deliverState = nil + if app.commiter != nil { + app.commiter(app.checkState.ctx) + } + var halt bool switch { diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 5cff5a206b2..b0cf381cc4c 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -70,6 +70,7 @@ type BaseApp struct { //nolint: maligned processProposal sdk.ProcessProposalHandler // the handler which runs on ABCI ProcessProposal prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes + commiter sdk.Commiter // logic to run during commit addrPeerFilter sdk.PeerFilter // filter peers by address and port idPeerFilter sdk.PeerFilter // filter peers by node ID fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed. diff --git a/baseapp/options.go b/baseapp/options.go index 2900cd798b5..ebbab425c39 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -167,6 +167,14 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { app.endBlocker = endBlocker } +func (app *BaseApp) SetCommiter(commiter sdk.Commiter) { + if app.sealed { + panic("SetCommiter() on sealed BaseApp") + } + + app.commiter = commiter +} + func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) { if app.sealed { panic("SetAnteHandler() on sealed BaseApp") diff --git a/telemetry/wrapper.go b/telemetry/wrapper.go index e6542df86e1..d354a7c8f2c 100644 --- a/telemetry/wrapper.go +++ b/telemetry/wrapper.go @@ -10,6 +10,7 @@ import ( const ( MetricKeyBeginBlocker = "begin_blocker" MetricKeyEndBlocker = "end_blocker" + MetricKeyCommiter = "commiter" MetricLabelNameModule = "module" ) diff --git a/types/abci.go b/types/abci.go index b0e272a825c..41ee1b65017 100644 --- a/types/abci.go +++ b/types/abci.go @@ -19,6 +19,10 @@ type BeginBlocker func(ctx Context, req abci.RequestBeginBlock) (abci.ResponseBe // e.g. BFT timestamps rather than block height for any periodic EndBlock logic type EndBlocker func(ctx Context, req abci.RequestEndBlock) (abci.ResponseEndBlock, error) +// Commiter runs code during commit after the block has been committed, and the `checkState` has been +// branched for the new block. +type Commiter func(ctx Context) + // PeerFilter responds to p2p filtering queries from Tendermint type PeerFilter func(info string) abci.ResponseQuery diff --git a/types/module/module.go b/types/module/module.go index ba73d3d9d7d..4db9ffddb85 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -212,6 +212,12 @@ type EndBlockAppModule interface { EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate } +// CommitAppModule is an extension interface that contains information about the AppModule and Commit. +type CommitAppModule interface { + AppModule + Commit(sdk.Context) +} + // GenesisOnlyAppModule is an AppModule that only has import/export functionality type GenesisOnlyAppModule struct { AppModuleGenesis @@ -258,6 +264,7 @@ type Manager struct { OrderExportGenesis []string OrderBeginBlockers []string OrderEndBlockers []string + OrderCommiters []string OrderMigrations []string } @@ -276,6 +283,7 @@ func NewManager(modules ...AppModule) *Manager { OrderExportGenesis: modulesStr, OrderBeginBlockers: modulesStr, OrderEndBlockers: modulesStr, + OrderCommiters: modulesStr, } } @@ -351,6 +359,11 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.OrderEndBlockers = moduleNames } +// SetOrderCommiters sets the order of set commiter calls +func (m *Manager) SetOrderCommiters(moduleNames ...string) { + m.OrderCommiters = moduleNames +} + // SetOrderMigrations sets the order of migrations to be run. If not set // then migrations will be run with an order defined in `DefaultMigrationsOrder`. func (m *Manager) SetOrderMigrations(moduleNames ...string) { @@ -706,6 +719,17 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (abci.Resp }, nil } +// Commit performs commit functionality for all modules. +func (m *Manager) Commit(ctx sdk.Context) { + for _, moduleName := range m.OrderCommiters { + module, ok := m.Modules[moduleName].(CommitAppModule) + if !ok { + continue + } + module.Commit(ctx) + } +} + // GetVersionMap gets consensus version from all modules func (m *Manager) GetVersionMap() VersionMap { vermap := make(VersionMap) From 862b4d86dbb22597e5a0662bbfa4ec482852c144 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Fri, 3 Feb 2023 11:57:42 -0500 Subject: [PATCH 02/16] Add tests for Commiter change (#5) --- baseapp/abci_test.go | 50 ++++++++++++ baseapp/baseapp_test.go | 3 + testutil/mock/types_module_module.go | 113 +++++++++++++++++++++++++++ types/module/module_test.go | 21 +++++ 4 files changed, 187 insertions(+) diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index b4e4abca024..058f463f1b8 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -11,6 +11,7 @@ import ( abci "github.com/cometbft/cometbft/abci/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" + tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/gogoproto/jsonpb" "github.com/stretchr/testify/require" @@ -598,6 +599,33 @@ func TestABCI_EndBlock(t *testing.T) { require.Equal(t, cp.Block.MaxGas, res.ConsensusParamUpdates.Block.MaxGas) } +func TestBaseApp_Commit(t *testing.T) { + db := dbm.NewMemDB() + name := t.Name() + logger := log.NewTestLogger(t) + + cp := &tmproto.ConsensusParams{ + Block: &tmproto.BlockParams{ + MaxGas: 5000000, + }, + } + + app := baseapp.NewBaseApp(name, logger, db, nil) + app.SetParamStore(¶mStore{db: dbm.NewMemDB()}) + app.InitChain(abci.RequestInitChain{ + ConsensusParams: cp, + }) + + wasCommiterCalled := false + app.SetCommiter(func(ctx sdk.Context) { + wasCommiterCalled = true + }) + app.Seal() + + app.Commit() + require.Equal(t, true, wasCommiterCalled) +} + func TestABCI_CheckTx(t *testing.T) { // This ante handler reads the key and checks that the value matches the // current counter. This ensures changes to the KVStore persist across @@ -1322,6 +1350,28 @@ func TestABCI_GetBlockRetentionHeight(t *testing.T) { } } +// Verifies that the Commiter is called with the checkState. +func TestCommiterCalledWithCheckState(t *testing.T) { + t.Parallel() + + logger := log.NewTestLogger(t) + db := dbm.NewMemDB() + name := t.Name() + app := baseapp.NewBaseApp(name, logger, db, nil) + + wasCommiterCalled := false + app.SetCommiter(func(ctx sdk.Context) { + // Make sure context is for next block + require.Equal(t, true, ctx.IsCheckTx()) + wasCommiterCalled = true + }) + + app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}}) + app.Commit() + + require.Equal(t, true, wasCommiterCalled) +} + func TestABCI_Proposal_HappyPath(t *testing.T) { anteKey := []byte("ante-key") pool := mempool.NewSenderNonceMempool() diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 47b06cf5ddf..ee8068bb045 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -388,6 +388,9 @@ func TestBaseAppOptionSeal(t *testing.T) { require.Panics(t, func() { suite.baseApp.SetEndBlocker(nil) }) + require.Panics(t, func() { + suite.baseApp.SetCommiter(nil) + }) require.Panics(t, func() { suite.baseApp.SetAnteHandler(nil) }) diff --git a/testutil/mock/types_module_module.go b/testutil/mock/types_module_module.go index 8b3a79c80fa..ca77ba57f18 100644 --- a/testutil/mock/types_module_module.go +++ b/testutil/mock/types_module_module.go @@ -879,3 +879,116 @@ func (mr *MockEndBlockAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 inter mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockEndBlockAppModule)(nil).RegisterLegacyAminoCodec), arg0) } + +// MockCommitAppModule is a mock of CommitAppModule interface. +type MockCommitAppModule struct { + ctrl *gomock.Controller + recorder *MockCommitAppModuleMockRecorder +} + +// MockCommitAppModuleMockRecorder is the mock recorder for MockCommitAppModule. +type MockCommitAppModuleMockRecorder struct { + mock *MockCommitAppModule +} + +// NewMockCommitAppModule creates a new mock instance. +func NewMockCommitAppModule(ctrl *gomock.Controller) *MockCommitAppModule { + mock := &MockCommitAppModule{ctrl: ctrl} + mock.recorder = &MockCommitAppModuleMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockCommitAppModule) EXPECT() *MockCommitAppModuleMockRecorder { + return m.recorder +} + +// Commit mocks base method. +func (m *MockCommitAppModule) Commit(arg0 types1.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Commit", arg0) +} + +// Commit indicates an expected call of Commit. +func (mr *MockCommitAppModuleMockRecorder) Commit(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockCommitAppModule)(nil).Commit), arg0) +} + +// GetQueryCmd mocks base method. +func (m *MockCommitAppModule) GetQueryCmd() *cobra.Command { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetQueryCmd") + ret0, _ := ret[0].(*cobra.Command) + return ret0 +} + +// GetQueryCmd indicates an expected call of GetQueryCmd. +func (mr *MockCommitAppModuleMockRecorder) GetQueryCmd() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockCommitAppModule)(nil).GetQueryCmd)) +} + +// GetTxCmd mocks base method. +func (m *MockCommitAppModule) GetTxCmd() *cobra.Command { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTxCmd") + ret0, _ := ret[0].(*cobra.Command) + return ret0 +} + +// GetTxCmd indicates an expected call of GetTxCmd. +func (mr *MockCommitAppModuleMockRecorder) GetTxCmd() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockCommitAppModule)(nil).GetTxCmd)) +} + +// Name mocks base method. +func (m *MockCommitAppModule) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockCommitAppModuleMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockCommitAppModule)(nil).Name)) +} + +// RegisterGRPCGatewayRoutes mocks base method. +func (m *MockCommitAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterGRPCGatewayRoutes", arg0, arg1) +} + +// RegisterGRPCGatewayRoutes indicates an expected call of RegisterGRPCGatewayRoutes. +func (mr *MockCommitAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1) +} + +// RegisterInterfaces mocks base method. +func (m *MockCommitAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterInterfaces", arg0) +} + +// RegisterInterfaces indicates an expected call of RegisterInterfaces. +func (mr *MockCommitAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterInterfaces), arg0) +} + +// RegisterLegacyAminoCodec mocks base method. +func (m *MockCommitAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterLegacyAminoCodec", arg0) +} + +// RegisterLegacyAminoCodec indicates an expected call of RegisterLegacyAminoCodec. +func (mr *MockCommitAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterLegacyAminoCodec), arg0) +} diff --git a/types/module/module_test.go b/types/module/module_test.go index 89a92417236..45d942ed789 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -128,6 +128,10 @@ func TestManagerOrderSetters(t *testing.T) { require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers) mm.SetOrderEndBlockers("module2", "module1", "module3") require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) + + require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderCommiters) + mm.SetOrderCommiters("module2", "module1", "module3") + require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderCommiters) } func TestManager_RegisterInvariants(t *testing.T) { @@ -319,6 +323,23 @@ func TestManager_EndBlock(t *testing.T) { require.Error(t, err) } +func TestManager_Commit(t *testing.T) { + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + + mockAppModule1 := mock.NewMockCommitAppModule(mockCtrl) + mockAppModule2 := mock.NewMockCommitAppModule(mockCtrl) + mockAppModule1.EXPECT().Name().Times(2).Return("module1") + mockAppModule2.EXPECT().Name().Times(2).Return("module2") + mm := module.NewManager(mockAppModule1, mockAppModule2) + require.NotNil(t, mm) + require.Equal(t, 2, len(mm.Modules)) + + mockAppModule1.EXPECT().Commit(gomock.Any()).Times(1) + mockAppModule2.EXPECT().Commit(gomock.Any()).Times(1) + mm.Commit(sdk.Context{}) +} + // Core API exclusive tests func TestCoreAPIManager(t *testing.T) { mockCtrl := gomock.NewController(t) From 1d72615b03a5744e8b25f900ee534b5e71cf24b0 Mon Sep 17 00:00:00 2001 From: dydxwill <119354122+dydxwill@users.noreply.github.com> Date: Thu, 23 Feb 2023 10:37:28 -0500 Subject: [PATCH 03/16] add precommit callback (#7) --- baseapp/abci.go | 4 + baseapp/abci_test.go | 50 +++++++++++- baseapp/baseapp.go | 1 + baseapp/baseapp_test.go | 3 + baseapp/options.go | 8 ++ testutil/mock/types_module_module.go | 113 +++++++++++++++++++++++++++ types/abci.go | 3 + types/module/module.go | 36 +++++++-- types/module/module_test.go | 25 +++++- 9 files changed, 234 insertions(+), 9 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index a7b185b6dee..5443cafcbcd 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -485,6 +485,10 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // Commit. Use the header from this latest block. app.setState(runTxModeCheck, header) + if app.precommiter != nil { + app.precommiter(app.deliverState.ctx) + } + // empty/reset the deliver state app.deliverState = nil diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 058f463f1b8..13ea01314be 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -626,6 +626,33 @@ func TestBaseApp_Commit(t *testing.T) { require.Equal(t, true, wasCommiterCalled) } +func TestBaseApp_Precommit(t *testing.T) { + db := dbm.NewMemDB() + name := t.Name() + logger := log.NewTestLogger(t) + + cp := &tmproto.ConsensusParams{ + Block: &tmproto.BlockParams{ + MaxGas: 5000000, + }, + } + + app := baseapp.NewBaseApp(name, logger, db, nil) + app.SetParamStore(¶mStore{db: dbm.NewMemDB()}) + app.InitChain(abci.RequestInitChain{ + ConsensusParams: cp, + }) + + wasPrecommiterCalled := false + app.SetPrecommiter(func(ctx sdk.Context) { + wasPrecommiterCalled = true + }) + app.Seal() + + app.Commit() + require.Equal(t, true, wasPrecommiterCalled) +} + func TestABCI_CheckTx(t *testing.T) { // This ante handler reads the key and checks that the value matches the // current counter. This ensures changes to the KVStore persist across @@ -1361,7 +1388,6 @@ func TestCommiterCalledWithCheckState(t *testing.T) { wasCommiterCalled := false app.SetCommiter(func(ctx sdk.Context) { - // Make sure context is for next block require.Equal(t, true, ctx.IsCheckTx()) wasCommiterCalled = true }) @@ -1372,6 +1398,28 @@ func TestCommiterCalledWithCheckState(t *testing.T) { require.Equal(t, true, wasCommiterCalled) } +// Verifies that the Precommiter is called with the deliverState. +func TestPrecommiterCalledWithDeliverState(t *testing.T) { + t.Parallel() + + logger := log.NewTestLogger(t) + db := dbm.NewMemDB() + name := t.Name() + app := baseapp.NewBaseApp(name, logger, db, nil) + + wasPrecommiterCalled := false + app.SetPrecommiter(func(ctx sdk.Context) { + require.Equal(t, false, ctx.IsCheckTx()) + require.Equal(t, false, ctx.IsReCheckTx()) + wasPrecommiterCalled = true + }) + + app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}}) + app.Commit() + + require.Equal(t, true, wasPrecommiterCalled) +} + func TestABCI_Proposal_HappyPath(t *testing.T) { anteKey := []byte("ante-key") pool := mempool.NewSenderNonceMempool() diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index b0cf381cc4c..f66049c35f9 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -71,6 +71,7 @@ type BaseApp struct { //nolint: maligned prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes commiter sdk.Commiter // logic to run during commit + precommiter sdk.Precommiter // logic to run during commit using the deliverState addrPeerFilter sdk.PeerFilter // filter peers by address and port idPeerFilter sdk.PeerFilter // filter peers by node ID fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed. diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index ee8068bb045..76cfa2421e8 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -391,6 +391,9 @@ func TestBaseAppOptionSeal(t *testing.T) { require.Panics(t, func() { suite.baseApp.SetCommiter(nil) }) + require.Panics(t, func() { + suite.baseApp.SetPrecommiter(nil) + }) require.Panics(t, func() { suite.baseApp.SetAnteHandler(nil) }) diff --git a/baseapp/options.go b/baseapp/options.go index ebbab425c39..bd4ac7b4548 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -175,6 +175,14 @@ func (app *BaseApp) SetCommiter(commiter sdk.Commiter) { app.commiter = commiter } +func (app *BaseApp) SetPrecommiter(precommiter sdk.Precommiter) { + if app.sealed { + panic("SetPrecommiter() on sealed BaseApp") + } + + app.precommiter = precommiter +} + func (app *BaseApp) SetAnteHandler(ah sdk.AnteHandler) { if app.sealed { panic("SetAnteHandler() on sealed BaseApp") diff --git a/testutil/mock/types_module_module.go b/testutil/mock/types_module_module.go index ca77ba57f18..7887248b621 100644 --- a/testutil/mock/types_module_module.go +++ b/testutil/mock/types_module_module.go @@ -992,3 +992,116 @@ func (mr *MockCommitAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interfa mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterLegacyAminoCodec), arg0) } + +// MockPrecommitAppModule is a mock of PrecommitAppModule interface. +type MockPrecommitAppModule struct { + ctrl *gomock.Controller + recorder *MockPrecommitAppModuleMockRecorder +} + +// MockPrecommitAppModuleMockRecorder is the mock recorder for MockPrecommitAppModule. +type MockPrecommitAppModuleMockRecorder struct { + mock *MockPrecommitAppModule +} + +// NewMockPrecommitAppModule creates a new mock instance. +func NewMockPrecommitAppModule(ctrl *gomock.Controller) *MockPrecommitAppModule { + mock := &MockPrecommitAppModule{ctrl: ctrl} + mock.recorder = &MockPrecommitAppModuleMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockPrecommitAppModule) EXPECT() *MockPrecommitAppModuleMockRecorder { + return m.recorder +} + +// GetQueryCmd mocks base method. +func (m *MockPrecommitAppModule) GetQueryCmd() *cobra.Command { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetQueryCmd") + ret0, _ := ret[0].(*cobra.Command) + return ret0 +} + +// GetQueryCmd indicates an expected call of GetQueryCmd. +func (mr *MockPrecommitAppModuleMockRecorder) GetQueryCmd() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockPrecommitAppModule)(nil).GetQueryCmd)) +} + +// GetTxCmd mocks base method. +func (m *MockPrecommitAppModule) GetTxCmd() *cobra.Command { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTxCmd") + ret0, _ := ret[0].(*cobra.Command) + return ret0 +} + +// GetTxCmd indicates an expected call of GetTxCmd. +func (mr *MockPrecommitAppModuleMockRecorder) GetTxCmd() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockPrecommitAppModule)(nil).GetTxCmd)) +} + +// Name mocks base method. +func (m *MockPrecommitAppModule) Name() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Name") + ret0, _ := ret[0].(string) + return ret0 +} + +// Name indicates an expected call of Name. +func (mr *MockPrecommitAppModuleMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockPrecommitAppModule)(nil).Name)) +} + +// Precommit mocks base method. +func (m *MockPrecommitAppModule) Precommit(arg0 types1.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "Precommit", arg0) +} + +// Precommit indicates an expected call of Precommit. +func (mr *MockPrecommitAppModuleMockRecorder) Precommit(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Precommit", reflect.TypeOf((*MockPrecommitAppModule)(nil).Precommit), arg0) +} + +// RegisterGRPCGatewayRoutes mocks base method. +func (m *MockPrecommitAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterGRPCGatewayRoutes", arg0, arg1) +} + +// RegisterGRPCGatewayRoutes indicates an expected call of RegisterGRPCGatewayRoutes. +func (mr *MockPrecommitAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1) +} + +// RegisterInterfaces mocks base method. +func (m *MockPrecommitAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterInterfaces", arg0) +} + +// RegisterInterfaces indicates an expected call of RegisterInterfaces. +func (mr *MockPrecommitAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterInterfaces), arg0) +} + +// RegisterLegacyAminoCodec mocks base method. +func (m *MockPrecommitAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "RegisterLegacyAminoCodec", arg0) +} + +// RegisterLegacyAminoCodec indicates an expected call of RegisterLegacyAminoCodec. +func (mr *MockPrecommitAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockPrecommitAppModule)(nil).RegisterLegacyAminoCodec), arg0) +} diff --git a/types/abci.go b/types/abci.go index 41ee1b65017..12767435424 100644 --- a/types/abci.go +++ b/types/abci.go @@ -23,6 +23,9 @@ type EndBlocker func(ctx Context, req abci.RequestEndBlock) (abci.ResponseEndBlo // branched for the new block. type Commiter func(ctx Context) +// Precommiter runs code during commit before the `deliverState` is reset. +type Precommiter func(ctx Context) + // PeerFilter responds to p2p filtering queries from Tendermint type PeerFilter func(info string) abci.ResponseQuery diff --git a/types/module/module.go b/types/module/module.go index 4db9ffddb85..b584461faa9 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -218,6 +218,12 @@ type CommitAppModule interface { Commit(sdk.Context) } +// PreommitAppModule is an extension interface that contains information about the AppModule and Precommit. +type PrecommitAppModule interface { + AppModule + Precommit(sdk.Context) +} + // GenesisOnlyAppModule is an AppModule that only has import/export functionality type GenesisOnlyAppModule struct { AppModuleGenesis @@ -265,6 +271,7 @@ type Manager struct { OrderBeginBlockers []string OrderEndBlockers []string OrderCommiters []string + OrderPrecommiters []string OrderMigrations []string } @@ -282,8 +289,9 @@ func NewManager(modules ...AppModule) *Manager { OrderInitGenesis: modulesStr, OrderExportGenesis: modulesStr, OrderBeginBlockers: modulesStr, - OrderEndBlockers: modulesStr, OrderCommiters: modulesStr, + OrderPrecommiters: modulesStr, + OrderEndBlockers: modulesStr, } } @@ -348,6 +356,16 @@ func (m *Manager) SetOrderBeginBlockers(moduleNames ...string) { m.OrderBeginBlockers = moduleNames } +// SetOrderCommiters sets the order of set commiter calls +func (m *Manager) SetOrderCommiters(moduleNames ...string) { + m.OrderCommiters = moduleNames +} + +// SetOrderPrecommiters sets the order of set precommiter calls +func (m *Manager) SetOrderPrecommiters(moduleNames ...string) { + m.OrderPrecommiters = moduleNames +} + // SetOrderEndBlockers sets the order of set end-blocker calls func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames, @@ -359,11 +377,6 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.OrderEndBlockers = moduleNames } -// SetOrderCommiters sets the order of set commiter calls -func (m *Manager) SetOrderCommiters(moduleNames ...string) { - m.OrderCommiters = moduleNames -} - // SetOrderMigrations sets the order of migrations to be run. If not set // then migrations will be run with an order defined in `DefaultMigrationsOrder`. func (m *Manager) SetOrderMigrations(moduleNames ...string) { @@ -730,6 +743,17 @@ func (m *Manager) Commit(ctx sdk.Context) { } } +// Precommit performs precommit functionality for all modules. +func (m *Manager) Precommit(ctx sdk.Context) { + for _, moduleName := range m.OrderPrecommiters { + module, ok := m.Modules[moduleName].(PrecommitAppModule) + if !ok { + continue + } + module.Precommit(ctx) + } +} + // GetVersionMap gets consensus version from all modules func (m *Manager) GetVersionMap() VersionMap { vermap := make(VersionMap) diff --git a/types/module/module_test.go b/types/module/module_test.go index 45d942ed789..cca63e0a629 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -130,8 +130,12 @@ func TestManagerOrderSetters(t *testing.T) { require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderCommiters) - mm.SetOrderCommiters("module2", "module1", "module3") - require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderCommiters) + mm.SetOrderCommiters("module3", "module2", "module1") + require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderCommiters) + + require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) + mm.SetOrderPrecommiters("module3", "module2", "module1") + require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters) } func TestManager_RegisterInvariants(t *testing.T) { @@ -340,6 +344,23 @@ func TestManager_Commit(t *testing.T) { mm.Commit(sdk.Context{}) } +func TestManager_Precommit(t *testing.T) { + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + + mockAppModule1 := mock.NewMockPrecommitAppModule(mockCtrl) + mockAppModule2 := mock.NewMockPrecommitAppModule(mockCtrl) + mockAppModule1.EXPECT().Name().Times(2).Return("module1") + mockAppModule2.EXPECT().Name().Times(2).Return("module2") + mm := module.NewManager(mockAppModule1, mockAppModule2) + require.NotNil(t, mm) + require.Equal(t, 2, len(mm.Modules)) + + mockAppModule1.EXPECT().Precommit(gomock.Any()).Times(1) + mockAppModule2.EXPECT().Precommit(gomock.Any()).Times(1) + mm.Precommit(sdk.Context{}) +} + // Core API exclusive tests func TestCoreAPIManager(t *testing.T) { mockCtrl := gomock.NewController(t) From 74ef20a992cf43ec1706f7aad995782db4d4a4d2 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 22 Mar 2023 17:21:17 -0400 Subject: [PATCH 04/16] lint --- baseapp/abci_test.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 13ea01314be..8e1806ff12c 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -11,7 +11,6 @@ import ( abci "github.com/cometbft/cometbft/abci/types" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" - tmproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/cosmos/gogoproto/jsonpb" "github.com/stretchr/testify/require" @@ -604,8 +603,8 @@ func TestBaseApp_Commit(t *testing.T) { name := t.Name() logger := log.NewTestLogger(t) - cp := &tmproto.ConsensusParams{ - Block: &tmproto.BlockParams{ + cp := &cmtproto.ConsensusParams{ + Block: &cmtproto.BlockParams{ MaxGas: 5000000, }, } @@ -631,8 +630,8 @@ func TestBaseApp_Precommit(t *testing.T) { name := t.Name() logger := log.NewTestLogger(t) - cp := &tmproto.ConsensusParams{ - Block: &tmproto.BlockParams{ + cp := &cmtproto.ConsensusParams{ + Block: &cmtproto.BlockParams{ MaxGas: 5000000, }, } @@ -1392,7 +1391,7 @@ func TestCommiterCalledWithCheckState(t *testing.T) { wasCommiterCalled = true }) - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}}) + app.BeginBlock(abci.RequestBeginBlock{Header: cmtproto.Header{Height: 1}}) app.Commit() require.Equal(t, true, wasCommiterCalled) @@ -1414,7 +1413,7 @@ func TestPrecommiterCalledWithDeliverState(t *testing.T) { wasPrecommiterCalled = true }) - app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: 1}}) + app.BeginBlock(abci.RequestBeginBlock{Header: cmtproto.Header{Height: 1}}) app.Commit() require.Equal(t, true, wasPrecommiterCalled) From a491aaf2dba7dd28da60374f9b719e6767391d2a Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Fri, 24 Mar 2023 17:21:52 -0400 Subject: [PATCH 05/16] Rename Commit to PrepareCheckState --- baseapp/abci.go | 4 +- baseapp/abci_test.go | 22 ++++---- baseapp/baseapp.go | 26 ++++----- baseapp/baseapp_test.go | 2 +- baseapp/options.go | 6 +- telemetry/wrapper.go | 9 +-- testutil/mock/types_module_module.go | 82 ++++++++++++++-------------- types/abci.go | 6 +- types/module/module.go | 53 +++++++++--------- types/module/module_test.go | 18 +++--- 10 files changed, 115 insertions(+), 113 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 5443cafcbcd..96593493141 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -492,8 +492,8 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // empty/reset the deliver state app.deliverState = nil - if app.commiter != nil { - app.commiter(app.checkState.ctx) + if app.prepareCheckStater != nil { + app.prepareCheckStater(app.checkState.ctx) } var halt bool diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 8e1806ff12c..3cf8ac951e9 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -598,7 +598,7 @@ func TestABCI_EndBlock(t *testing.T) { require.Equal(t, cp.Block.MaxGas, res.ConsensusParamUpdates.Block.MaxGas) } -func TestBaseApp_Commit(t *testing.T) { +func TestBaseApp_PrepareCheckState(t *testing.T) { db := dbm.NewMemDB() name := t.Name() logger := log.NewTestLogger(t) @@ -615,14 +615,14 @@ func TestBaseApp_Commit(t *testing.T) { ConsensusParams: cp, }) - wasCommiterCalled := false - app.SetCommiter(func(ctx sdk.Context) { - wasCommiterCalled = true + wasPrepareCheckStateCalled := false + app.SetPrepareCheckState(func(ctx sdk.Context) { + wasPrepareCheckStateCalled = true }) app.Seal() app.Commit() - require.Equal(t, true, wasCommiterCalled) + require.Equal(t, true, wasPrepareCheckStateCalled) } func TestBaseApp_Precommit(t *testing.T) { @@ -1376,8 +1376,8 @@ func TestABCI_GetBlockRetentionHeight(t *testing.T) { } } -// Verifies that the Commiter is called with the checkState. -func TestCommiterCalledWithCheckState(t *testing.T) { +// Verifies that PrepareCheckState is called with the checkState. +func TestPrepareCheckStateCalledWithCheckState(t *testing.T) { t.Parallel() logger := log.NewTestLogger(t) @@ -1385,16 +1385,16 @@ func TestCommiterCalledWithCheckState(t *testing.T) { name := t.Name() app := baseapp.NewBaseApp(name, logger, db, nil) - wasCommiterCalled := false - app.SetCommiter(func(ctx sdk.Context) { + wasPrepareCheckStateCalled := false + app.SetPrepareCheckState(func(ctx sdk.Context) { require.Equal(t, true, ctx.IsCheckTx()) - wasCommiterCalled = true + wasPrepareCheckStateCalled = true }) app.BeginBlock(abci.RequestBeginBlock{Header: cmtproto.Header{Height: 1}}) app.Commit() - require.Equal(t, true, wasCommiterCalled) + require.Equal(t, true, wasPrepareCheckStateCalled) } // Verifies that the Precommiter is called with the deliverState. diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index f66049c35f9..65c337377d6 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -62,19 +62,19 @@ type BaseApp struct { //nolint: maligned txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx txEncoder sdk.TxEncoder // marshal sdk.Tx into []byte - mempool mempool.Mempool // application side mempool - anteHandler sdk.AnteHandler // ante handler for fee and auth - postHandler sdk.PostHandler // post handler, optional, e.g. for tips - initChainer sdk.InitChainer // initialize state with validators and state blob - beginBlocker sdk.BeginBlocker // logic to run before any txs - processProposal sdk.ProcessProposalHandler // the handler which runs on ABCI ProcessProposal - prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal - endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes - commiter sdk.Commiter // logic to run during commit - precommiter sdk.Precommiter // logic to run during commit using the deliverState - addrPeerFilter sdk.PeerFilter // filter peers by address and port - idPeerFilter sdk.PeerFilter // filter peers by node ID - fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed. + mempool mempool.Mempool // application side mempool + anteHandler sdk.AnteHandler // ante handler for fee and auth + postHandler sdk.PostHandler // post handler, optional, e.g. for tips + initChainer sdk.InitChainer // initialize state with validators and state blob + beginBlocker sdk.BeginBlocker // logic to run before any txs + processProposal sdk.ProcessProposalHandler // the handler which runs on ABCI ProcessProposal + prepareProposal sdk.PrepareProposalHandler // the handler which runs on ABCI PrepareProposal + endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes + prepareCheckStater sdk.PrepareCheckStater // logic to run during commit using the checkState + precommiter sdk.Precommiter // logic to run during commit using the deliverState + addrPeerFilter sdk.PeerFilter // filter peers by address and port + idPeerFilter sdk.PeerFilter // filter peers by node ID + fauxMerkleMode bool // if true, IAVL MountStores uses MountStoresDB for simulation speed. // manages snapshots, i.e. dumps of app state at certain intervals snapshotManager *snapshots.Manager diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 76cfa2421e8..a8f5d884892 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -389,7 +389,7 @@ func TestBaseAppOptionSeal(t *testing.T) { suite.baseApp.SetEndBlocker(nil) }) require.Panics(t, func() { - suite.baseApp.SetCommiter(nil) + suite.baseApp.SetPrepareCheckState(nil) }) require.Panics(t, func() { suite.baseApp.SetPrecommiter(nil) diff --git a/baseapp/options.go b/baseapp/options.go index bd4ac7b4548..d227a3d1f0e 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -167,12 +167,12 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { app.endBlocker = endBlocker } -func (app *BaseApp) SetCommiter(commiter sdk.Commiter) { +func (app *BaseApp) SetPrepareCheckState(prepareCheckStater sdk.PrepareCheckStater) { if app.sealed { - panic("SetCommiter() on sealed BaseApp") + panic("SetPrepareCheckState() on sealed BaseApp") } - app.commiter = commiter + app.prepareCheckStater = prepareCheckStater } func (app *BaseApp) SetPrecommiter(precommiter sdk.Precommiter) { diff --git a/telemetry/wrapper.go b/telemetry/wrapper.go index d354a7c8f2c..c669c816a96 100644 --- a/telemetry/wrapper.go +++ b/telemetry/wrapper.go @@ -8,10 +8,11 @@ import ( // Common metric key constants const ( - MetricKeyBeginBlocker = "begin_blocker" - MetricKeyEndBlocker = "end_blocker" - MetricKeyCommiter = "commiter" - MetricLabelNameModule = "module" + MetricKeyBeginBlocker = "begin_blocker" + MetricKeyEndBlocker = "end_blocker" + MetricKeyPrepareCheckStater = "prepare_check_stater" + MetricKeyPrecommiter = "precommiter" + MetricLabelNameModule = "module" ) // NewLabel creates a new instance of Label with name and value diff --git a/testutil/mock/types_module_module.go b/testutil/mock/types_module_module.go index 7887248b621..d84a80d2d78 100644 --- a/testutil/mock/types_module_module.go +++ b/testutil/mock/types_module_module.go @@ -880,43 +880,31 @@ func (mr *MockEndBlockAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 inter return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockEndBlockAppModule)(nil).RegisterLegacyAminoCodec), arg0) } -// MockCommitAppModule is a mock of CommitAppModule interface. -type MockCommitAppModule struct { +// MockPrepareCheckStateAppModule is a mock of PrepareCheckStateAppModule interface. +type MockPrepareCheckStateAppModule struct { ctrl *gomock.Controller - recorder *MockCommitAppModuleMockRecorder + recorder *MockPrepareCheckStateAppModuleMockRecorder } -// MockCommitAppModuleMockRecorder is the mock recorder for MockCommitAppModule. -type MockCommitAppModuleMockRecorder struct { - mock *MockCommitAppModule +// MockPrepareCheckStateAppModuleMockRecorder is the mock recorder for MockPrepareCheckStateAppModule. +type MockPrepareCheckStateAppModuleMockRecorder struct { + mock *MockPrepareCheckStateAppModule } -// NewMockCommitAppModule creates a new mock instance. -func NewMockCommitAppModule(ctrl *gomock.Controller) *MockCommitAppModule { - mock := &MockCommitAppModule{ctrl: ctrl} - mock.recorder = &MockCommitAppModuleMockRecorder{mock} +// NewMockPrepareCheckStateAppModule creates a new mock instance. +func NewMockPrepareCheckStateAppModule(ctrl *gomock.Controller) *MockPrepareCheckStateAppModule { + mock := &MockPrepareCheckStateAppModule{ctrl: ctrl} + mock.recorder = &MockPrepareCheckStateAppModuleMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use. -func (m *MockCommitAppModule) EXPECT() *MockCommitAppModuleMockRecorder { +func (m *MockPrepareCheckStateAppModule) EXPECT() *MockPrepareCheckStateAppModuleMockRecorder { return m.recorder } -// Commit mocks base method. -func (m *MockCommitAppModule) Commit(arg0 types1.Context) { - m.ctrl.T.Helper() - m.ctrl.Call(m, "Commit", arg0) -} - -// Commit indicates an expected call of Commit. -func (mr *MockCommitAppModuleMockRecorder) Commit(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockCommitAppModule)(nil).Commit), arg0) -} - // GetQueryCmd mocks base method. -func (m *MockCommitAppModule) GetQueryCmd() *cobra.Command { +func (m *MockPrepareCheckStateAppModule) GetQueryCmd() *cobra.Command { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetQueryCmd") ret0, _ := ret[0].(*cobra.Command) @@ -924,13 +912,13 @@ func (m *MockCommitAppModule) GetQueryCmd() *cobra.Command { } // GetQueryCmd indicates an expected call of GetQueryCmd. -func (mr *MockCommitAppModuleMockRecorder) GetQueryCmd() *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) GetQueryCmd() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockCommitAppModule)(nil).GetQueryCmd)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetQueryCmd", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).GetQueryCmd)) } // GetTxCmd mocks base method. -func (m *MockCommitAppModule) GetTxCmd() *cobra.Command { +func (m *MockPrepareCheckStateAppModule) GetTxCmd() *cobra.Command { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetTxCmd") ret0, _ := ret[0].(*cobra.Command) @@ -938,13 +926,13 @@ func (m *MockCommitAppModule) GetTxCmd() *cobra.Command { } // GetTxCmd indicates an expected call of GetTxCmd. -func (mr *MockCommitAppModuleMockRecorder) GetTxCmd() *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) GetTxCmd() *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockCommitAppModule)(nil).GetTxCmd)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTxCmd", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).GetTxCmd)) } // Name mocks base method. -func (m *MockCommitAppModule) Name() string { +func (m *MockPrepareCheckStateAppModule) Name() string { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Name") ret0, _ := ret[0].(string) @@ -952,45 +940,57 @@ func (m *MockCommitAppModule) Name() string { } // Name indicates an expected call of Name. -func (mr *MockCommitAppModuleMockRecorder) Name() *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) Name() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).Name)) +} + +// PrepareCheckState mocks base method. +func (m *MockPrepareCheckStateAppModule) PrepareCheckState(arg0 types1.Context) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "PrepareCheckState", arg0) +} + +// PrepareCheckState indicates an expected call of PrepareCheckState. +func (mr *MockPrepareCheckStateAppModuleMockRecorder) PrepareCheckState(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Name", reflect.TypeOf((*MockCommitAppModule)(nil).Name)) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PrepareCheckState", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).PrepareCheckState), arg0) } // RegisterGRPCGatewayRoutes mocks base method. -func (m *MockCommitAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) { +func (m *MockPrepareCheckStateAppModule) RegisterGRPCGatewayRoutes(arg0 client.Context, arg1 *runtime.ServeMux) { m.ctrl.T.Helper() m.ctrl.Call(m, "RegisterGRPCGatewayRoutes", arg0, arg1) } // RegisterGRPCGatewayRoutes indicates an expected call of RegisterGRPCGatewayRoutes. -func (mr *MockCommitAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterGRPCGatewayRoutes(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterGRPCGatewayRoutes", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterGRPCGatewayRoutes), arg0, arg1) } // RegisterInterfaces mocks base method. -func (m *MockCommitAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) { +func (m *MockPrepareCheckStateAppModule) RegisterInterfaces(arg0 types0.InterfaceRegistry) { m.ctrl.T.Helper() m.ctrl.Call(m, "RegisterInterfaces", arg0) } // RegisterInterfaces indicates an expected call of RegisterInterfaces. -func (mr *MockCommitAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterInterfaces(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterInterfaces), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterInterfaces", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterInterfaces), arg0) } // RegisterLegacyAminoCodec mocks base method. -func (m *MockCommitAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) { +func (m *MockPrepareCheckStateAppModule) RegisterLegacyAminoCodec(arg0 *codec.LegacyAmino) { m.ctrl.T.Helper() m.ctrl.Call(m, "RegisterLegacyAminoCodec", arg0) } // RegisterLegacyAminoCodec indicates an expected call of RegisterLegacyAminoCodec. -func (mr *MockCommitAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call { +func (mr *MockPrepareCheckStateAppModuleMockRecorder) RegisterLegacyAminoCodec(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockCommitAppModule)(nil).RegisterLegacyAminoCodec), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterLegacyAminoCodec", reflect.TypeOf((*MockPrepareCheckStateAppModule)(nil).RegisterLegacyAminoCodec), arg0) } // MockPrecommitAppModule is a mock of PrecommitAppModule interface. diff --git a/types/abci.go b/types/abci.go index 12767435424..2f87dcf11c3 100644 --- a/types/abci.go +++ b/types/abci.go @@ -19,9 +19,9 @@ type BeginBlocker func(ctx Context, req abci.RequestBeginBlock) (abci.ResponseBe // e.g. BFT timestamps rather than block height for any periodic EndBlock logic type EndBlocker func(ctx Context, req abci.RequestEndBlock) (abci.ResponseEndBlock, error) -// Commiter runs code during commit after the block has been committed, and the `checkState` has been -// branched for the new block. -type Commiter func(ctx Context) +// PrepareCheckStater runs code during commit after the block has been committed, and the `checkState` +// has been branched for the new block. +type PrepareCheckStater func(ctx Context) // Precommiter runs code during commit before the `deliverState` is reset. type Precommiter func(ctx Context) diff --git a/types/module/module.go b/types/module/module.go index b584461faa9..0eb6e0f2126 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -212,10 +212,11 @@ type EndBlockAppModule interface { EndBlock(sdk.Context, abci.RequestEndBlock) []abci.ValidatorUpdate } -// CommitAppModule is an extension interface that contains information about the AppModule and Commit. -type CommitAppModule interface { +// PrepareCheckStateAppModule is an extension interface that contains information about the AppModule +// and PrepareCheckState. +type PrepareCheckStateAppModule interface { AppModule - Commit(sdk.Context) + PrepareCheckState(sdk.Context) } // PreommitAppModule is an extension interface that contains information about the AppModule and Precommit. @@ -265,14 +266,14 @@ func (GenesisOnlyAppModule) EndBlock(_ sdk.Context, _ abci.RequestEndBlock) []ab // Manager defines a module manager that provides the high level utility for managing and executing // operations for a group of modules type Manager struct { - Modules map[string]interface{} // interface{} is used now to support the legacy AppModule as well as new core appmodule.AppModule. - OrderInitGenesis []string - OrderExportGenesis []string - OrderBeginBlockers []string - OrderEndBlockers []string - OrderCommiters []string - OrderPrecommiters []string - OrderMigrations []string + Modules map[string]interface{} // interface{} is used now to support the legacy AppModule as well as new core appmodule.AppModule. + OrderInitGenesis []string + OrderExportGenesis []string + OrderBeginBlockers []string + OrderEndBlockers []string + OrderPrepareCheckStaters []string + OrderPrecommiters []string + OrderMigrations []string } // NewManager creates a new Manager object. @@ -285,13 +286,13 @@ func NewManager(modules ...AppModule) *Manager { } return &Manager{ - Modules: moduleMap, - OrderInitGenesis: modulesStr, - OrderExportGenesis: modulesStr, - OrderBeginBlockers: modulesStr, - OrderCommiters: modulesStr, - OrderPrecommiters: modulesStr, - OrderEndBlockers: modulesStr, + Modules: moduleMap, + OrderInitGenesis: modulesStr, + OrderExportGenesis: modulesStr, + OrderBeginBlockers: modulesStr, + OrderPrepareCheckStaters: modulesStr, + OrderPrecommiters: modulesStr, + OrderEndBlockers: modulesStr, } } @@ -356,9 +357,9 @@ func (m *Manager) SetOrderBeginBlockers(moduleNames ...string) { m.OrderBeginBlockers = moduleNames } -// SetOrderCommiters sets the order of set commiter calls -func (m *Manager) SetOrderCommiters(moduleNames ...string) { - m.OrderCommiters = moduleNames +// SetOrderPepareCheckStaters sets the order of set commiter calls +func (m *Manager) SetOrderPepareCheckStaters(moduleNames ...string) { + m.OrderPrepareCheckStaters = moduleNames } // SetOrderPrecommiters sets the order of set precommiter calls @@ -732,14 +733,14 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (abci.Resp }, nil } -// Commit performs commit functionality for all modules. -func (m *Manager) Commit(ctx sdk.Context) { - for _, moduleName := range m.OrderCommiters { - module, ok := m.Modules[moduleName].(CommitAppModule) +// PrepareCheckState performs functionality for preparing the check state for all modules. +func (m *Manager) PrepareCheckState(ctx sdk.Context) { + for _, moduleName := range m.OrderPrepareCheckStaters { + module, ok := m.Modules[moduleName].(PrepareCheckStateAppModule) if !ok { continue } - module.Commit(ctx) + module.PrepareCheckState(ctx) } } diff --git a/types/module/module_test.go b/types/module/module_test.go index cca63e0a629..b788eb7a4bc 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -129,9 +129,9 @@ func TestManagerOrderSetters(t *testing.T) { mm.SetOrderEndBlockers("module2", "module1", "module3") require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) - require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderCommiters) - mm.SetOrderCommiters("module3", "module2", "module1") - require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderCommiters) + require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters) + mm.SetOrderPepareCheckStaters("module3", "module2", "module1") + require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters) require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) mm.SetOrderPrecommiters("module3", "module2", "module1") @@ -327,21 +327,21 @@ func TestManager_EndBlock(t *testing.T) { require.Error(t, err) } -func TestManager_Commit(t *testing.T) { +func TestManager_PrepareCheckState(t *testing.T) { mockCtrl := gomock.NewController(t) t.Cleanup(mockCtrl.Finish) - mockAppModule1 := mock.NewMockCommitAppModule(mockCtrl) - mockAppModule2 := mock.NewMockCommitAppModule(mockCtrl) + mockAppModule1 := mock.NewMockPrepareCheckStateAppModule(mockCtrl) + mockAppModule2 := mock.NewMockPrepareCheckStateAppModule(mockCtrl) mockAppModule1.EXPECT().Name().Times(2).Return("module1") mockAppModule2.EXPECT().Name().Times(2).Return("module2") mm := module.NewManager(mockAppModule1, mockAppModule2) require.NotNil(t, mm) require.Equal(t, 2, len(mm.Modules)) - mockAppModule1.EXPECT().Commit(gomock.Any()).Times(1) - mockAppModule2.EXPECT().Commit(gomock.Any()).Times(1) - mm.Commit(sdk.Context{}) + mockAppModule1.EXPECT().PrepareCheckState(gomock.Any()).Times(1) + mockAppModule2.EXPECT().PrepareCheckState(gomock.Any()).Times(1) + mm.PrepareCheckState(sdk.Context{}) } func TestManager_Precommit(t *testing.T) { From d01e7ffdedb114737864439bab5d5330090f36c9 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Tue, 28 Mar 2023 11:59:28 -0400 Subject: [PATCH 06/16] Add documentation to module manager --- .../docs/building-modules/01-module-manager.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/docs/building-modules/01-module-manager.md b/docs/docs/building-modules/01-module-manager.md index bd226c730c8..1ad079db0c1 100644 --- a/docs/docs/building-modules/01-module-manager.md +++ b/docs/docs/building-modules/01-module-manager.md @@ -36,6 +36,8 @@ The above interfaces are mostly embedding smaller interfaces (extension interfac * [`HasConsensusVersion`](#hasconsensusversion): The extension interface for declaring a module consensus version. * [`BeginBlockAppModule`](#beginblockappmodule): The extension interface that contains information about the `AppModule` and `BeginBlock`. * [`EndBlockAppModule`](#endblockappmodule): The extension interface that contains information about the `AppModule` and `EndBlock`. +* [`PrecommitAppModule`](#precommitappmodule): The extension interface that contains information about the `AppModule` and `Precommit`. +* [`PrepareCheckStateAppModule`](#preparecheckstateappmodule): The extension interface that contains information about the `AppModule` and `PrepareCheckState`. The `AppModuleBasic` interface exists to define independent methods of the module, i.e. those that do not depend on other modules in the application. This allows for the construction of the basic application structure early in the application definition, generally in the `init()` function of the [main application file](../basics/00-app-anatomy.md#core-application-file). @@ -167,6 +169,18 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/types/module/module.go#L20 * `EndBlock(sdk.Context, abci.RequestEndBlock)`: This method gives module developers the option to implement logic that is automatically triggered at the end of each block. This is also where the module can inform the underlying consensus engine of validator set changes (e.g. the `staking` module). Implement empty if no logic needs to be triggered at the end of each block for this module. +### `PrecommitAppModule` + +The `PrecommitAppModule` is an extension interface from `AppModule`. All modules that have a `Precommit` method implement this interface. + +* `Precommit(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`deliverState`](../core/00-baseapp.md#state-updates) of the newly committed block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module. + +### `PrepareCheckStateAppModule` + +The `PrepareCheckStateAppModule` is an extension interface from `AppModule`. All modules that have a `PrepareCheckState` method implement this interface. + +* `PrepareCheckState(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`checkState`](../core/00-baseapp.md#state-updates) of the next block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module. + ### Implementing the Application Module Interfaces Typically, the various application module interfaces are implemented in a file called `module.go`, located in the module's folder (e.g. `./x/module/module.go`). @@ -228,6 +242,8 @@ The module manager is used throughout the application whenever an action on a co * `SetOrderExportGenesis(moduleNames ...string)`: Sets the order in which the [`ExportGenesis`](./08-genesis.md#exportgenesis) function of each module will be called in case of an export. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function). * `SetOrderBeginBlockers(moduleNames ...string)`: Sets the order in which the `BeginBlock()` function of each module will be called at the beginning of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function). * `SetOrderEndBlockers(moduleNames ...string)`: Sets the order in which the `EndBlock()` function of each module will be called at the end of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function). +* `SetOrderPrecommiters(moduleNames ...string)`: Sets the order in which the `Precommit()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function). +* `SetOrderPrepareCheckStaters(moduleNames ...string)`: Sets the order in which the `PrepareCheckState()` function of each module will be called during commit of each block. This function is generally called from the application's main [constructor function](../basics/00-app-anatomy.md#constructor-function). * `SetOrderMigrations(moduleNames ...string)`: Sets the order of migrations to be run. If not set then migrations will be run with an order defined in `DefaultMigrationsOrder`. * `RegisterInvariants(ir sdk.InvariantRegistry)`: Registers the [invariants](./07-invariants.md) of module implementing the `HasInvariants` interface. * `RegisterRoutes(router sdk.Router, queryRouter sdk.QueryRouter, legacyQuerierCdc *codec.LegacyAmino)`: Registers legacy [`Msg`](./02-messages-and-queries.md#messages) and [`querier`](./04-query-services.md#legacy-queriers) routes. @@ -237,6 +253,8 @@ The module manager is used throughout the application whenever an action on a co * `ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export. * `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of each modules implementing the `BeginBlockAppModule` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. * `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `EndBlockAppModule` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). +* `Precommit(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `PrecommitAppModule` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`deliverState`](../core/00-baseapp.md#state-updates). Writes to this state during the callback are not persisted. +* `PrepareCheckState(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `PrepareCheckStateAppModule` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../core/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../core/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block. Here's an example of a concrete integration within an `simapp`: From ee7016afa6f636c61152a448226092480cb3c447 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Tue, 28 Mar 2023 12:45:48 -0400 Subject: [PATCH 07/16] Fix implementation and docs --- baseapp/abci.go | 10 +++++----- docs/docs/building-modules/01-module-manager.md | 4 ++-- types/abci.go | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index 206b473f718..8825baa9dc9 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -457,6 +457,10 @@ func (app *BaseApp) Commit() abci.ResponseCommit { header := app.deliverState.ctx.BlockHeader() retainHeight := app.GetBlockRetentionHeight(header.Height) + if app.precommiter != nil { + app.precommiter(app.deliverState.ctx) + } + rms, ok := app.cms.(*rootmulti.Store) if ok { rms.SetCommitHeader(header) @@ -464,7 +468,7 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // Write the DeliverTx state into branched storage and commit the MultiStore. // The write to the DeliverTx state writes all state transitions to the root - // MultiStore (app.cms) so when Commit() is called is persists those values. + // MultiStore (app.cms) so when Commit() is called it persists those values. app.deliverState.ms.Write() commitID := app.cms.Commit() @@ -494,10 +498,6 @@ func (app *BaseApp) Commit() abci.ResponseCommit { // Commit. Use the header from this latest block. app.setState(runTxModeCheck, header) - if app.precommiter != nil { - app.precommiter(app.deliverState.ctx) - } - // empty/reset the deliver state app.deliverState = nil diff --git a/docs/docs/building-modules/01-module-manager.md b/docs/docs/building-modules/01-module-manager.md index 1ad079db0c1..a420a6f0983 100644 --- a/docs/docs/building-modules/01-module-manager.md +++ b/docs/docs/building-modules/01-module-manager.md @@ -173,7 +173,7 @@ https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/types/module/module.go#L20 The `PrecommitAppModule` is an extension interface from `AppModule`. All modules that have a `Precommit` method implement this interface. -* `Precommit(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`deliverState`](../core/00-baseapp.md#state-updates) of the newly committed block. Implement empty if no logic needs to be triggered during `Commit` of each block for this module. +* `Precommit(sdk.Context)`: This method gives module developers the option to implement logic that is automatically triggered during [`Commit'](../core/00-baseapp.md#commit) of each block using the [`deliverState`](../core/00-baseapp.md#state-updates) of the block to be committed. Implement empty if no logic needs to be triggered during `Commit` of each block for this module. ### `PrepareCheckStateAppModule` @@ -253,7 +253,7 @@ The module manager is used throughout the application whenever an action on a co * `ExportGenesisForModules(ctx sdk.Context, cdc codec.JSONCodec, modulesToExport []string)`: Behaves the same as `ExportGenesis`, except takes a list of modules to export. * `BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock)`: At the beginning of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#beginblock) and, in turn, calls the [`BeginBlock`](./05-beginblock-endblock.md) function of each modules implementing the `BeginBlockAppModule` interface, in the order defined in `OrderBeginBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseBeginBlock` which contains the aforementioned events. * `EndBlock(ctx sdk.Context, req abci.RequestEndBlock)`: At the end of each block, this function is called from [`BaseApp`](../core/00-baseapp.md#endblock) and, in turn, calls the [`EndBlock`](./05-beginblock-endblock.md) function of each modules implementing the `EndBlockAppModule` interface, in the order defined in `OrderEndBlockers`. It creates a child [context](../core/02-context.md) with an event manager to aggregate [events](../core/08-events.md) emitted from all modules. The function returns an `abci.ResponseEndBlock` which contains the aforementioned events, as well as validator set updates (if any). -* `Precommit(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `PrecommitAppModule` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`deliverState`](../core/00-baseapp.md#state-updates). Writes to this state during the callback are not persisted. +* `Precommit(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately before the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `Precommit` function of each modules implementing the `PrecommitAppModule` interface, in the order defined in `OrderPrecommiters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the newly committed block's [`deliverState`](../core/00-baseapp.md#state-updates). * `PrepareCheckState(ctx sdk.Context)`: During [`Commit`](../core/00-baseapp.md#commit), this function is called from `BaseApp` immediately after the [`deliverState`](../core/00-baseapp.md#state-updates) is written to the underlying [`rootMultiStore`](../core/04-store.md#commitmultistore) and, in turn calls the `PrepareCheckState` function of each module implementing the `PrepareCheckStateAppModule` interface, in the order defined in `OrderPrepareCheckStaters`. It creates a child [context](../core/02-context.md) where the underlying `CacheMultiStore` is that of the next block's [`checkState`](../core/00-baseapp.md#state-updates). Writes to this state will be present in the [`checkState`](../core/00-baseapp.md#state-updates) of the next block, and therefore this method can be used to prepare the `checkState` for the next block. Here's an example of a concrete integration within an `simapp`: diff --git a/types/abci.go b/types/abci.go index 2f87dcf11c3..263747d758b 100644 --- a/types/abci.go +++ b/types/abci.go @@ -23,7 +23,7 @@ type EndBlocker func(ctx Context, req abci.RequestEndBlock) (abci.ResponseEndBlo // has been branched for the new block. type PrepareCheckStater func(ctx Context) -// Precommiter runs code during commit before the `deliverState` is reset. +// Precommiter runs code during commit immediately before the `deliverState` is written to the `rootMultiStore`. type Precommiter func(ctx Context) // PeerFilter responds to p2p filtering queries from Tendermint From f4f81e2cb9acb2c15a0b2766210b6eb6ff3ac884 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Tue, 28 Mar 2023 13:05:34 -0400 Subject: [PATCH 08/16] Add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e89f696f1bd..d0775e03d35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,6 +60,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/groups) [#14879](https://github.com/cosmos/cosmos-sdk/pull/14879) Add `Query/Groups` query to get all the groups. * (x/genutil,cli) [#15147](https://github.com/cosmos/cosmos-sdk/pull/15147) Add `--initial-height` flag to cli init cmd to provide `genesis.json` with user defined initial block height * (x/gov) [#15151](https://github.com/cosmos/cosmos-sdk/pull/15151) Add `burn_vote_quorum`, `burn_proposal_deposit_prevote` and `burn_vote_veto` params to allow applications to decide if they would like to burn deposits +* (core) [#14860](https://github.com/cosmos/cosmos-sdk/pull/14860) Add `Precommit` and `PrepareCheckState` AppModule callbacks. ### Improvements From a557977caa33ea05e9d24738d2f62aaf4b444806 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 29 Mar 2023 10:30:00 -0400 Subject: [PATCH 09/16] Add assertions for Precommit/PrepareCheckState and tests --- types/module/module.go | 32 +++++++++++++------ types/module/module_test.go | 64 ++++++++++++++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 11 deletions(-) diff --git a/types/module/module.go b/types/module/module.go index 0eb6e0f2126..ba3b5ce545b 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -357,16 +357,6 @@ func (m *Manager) SetOrderBeginBlockers(moduleNames ...string) { m.OrderBeginBlockers = moduleNames } -// SetOrderPepareCheckStaters sets the order of set commiter calls -func (m *Manager) SetOrderPepareCheckStaters(moduleNames ...string) { - m.OrderPrepareCheckStaters = moduleNames -} - -// SetOrderPrecommiters sets the order of set precommiter calls -func (m *Manager) SetOrderPrecommiters(moduleNames ...string) { - m.OrderPrecommiters = moduleNames -} - // SetOrderEndBlockers sets the order of set end-blocker calls func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames, @@ -378,6 +368,28 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.OrderEndBlockers = moduleNames } +// SetOrderPrepareCheckStaters sets the order of set commiter calls +func (m *Manager) SetOrderPrepareCheckStaters(moduleNames ...string) { + m.assertNoForgottenModules("SetOrderPrepareCheckStaters", moduleNames, + func(moduleName string) bool { + module := m.Modules[moduleName] + _, hasPrepareCheckState := module.(PrepareCheckStateAppModule) + return !hasPrepareCheckState + }) + m.OrderPrepareCheckStaters = moduleNames +} + +// SetOrderPrecommiters sets the order of set precommiter calls +func (m *Manager) SetOrderPrecommiters(moduleNames ...string) { + m.assertNoForgottenModules("SetOrderPrecommiters", moduleNames, + func(moduleName string) bool { + module := m.Modules[moduleName] + _, hasPrecommit := module.(PrecommitAppModule) + return !hasPrecommit + }) + m.OrderPrecommiters = moduleNames +} + // SetOrderMigrations sets the order of migrations to be run. If not set // then migrations will be run with an order defined in `DefaultMigrationsOrder`. func (m *Manager) SetOrderMigrations(moduleNames ...string) { diff --git a/types/module/module_test.go b/types/module/module_test.go index b788eb7a4bc..2701309d122 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -100,6 +100,60 @@ func TestGenesisOnlyAppModule(t *testing.T) { goam.RegisterInvariants(mockInvariantRegistry) } +func TestAssertNoForgottenModules(t *testing.T) { + mockCtrl := gomock.NewController(t) + t.Cleanup(mockCtrl.Finish) + mockAppModule1 := mock.NewMockEndBlockAppModule(mockCtrl) + mockAppModule2 := mock.NewMockBeginBlockAppModule(mockCtrl) + mockAppModule3 := mock.NewMockCoreAppModule(mockCtrl) + mockAppModule4 := mock.NewMockPrecommitAppModule(mockCtrl) + mockAppModule5 := mock.NewMockPrepareCheckStateAppModule(mockCtrl) + + mockAppModule1.EXPECT().Name().Times(2).Return("module1") + mockAppModule2.EXPECT().Name().Times(2).Return("module2") + mockAppModule4.EXPECT().Name().Times(2).Return("module4") + mockAppModule5.EXPECT().Name().Times(2).Return("module5") + mm := module.NewManager( + mockAppModule1, + mockAppModule2, + module.CoreAppModuleBasicAdaptor("module3", mockAppModule3), + mockAppModule4, + mockAppModule5, + ) + require.NotNil(t, mm) + require.Equal(t, 5, len(mm.Modules)) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderInitGenesis) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderInitGenesis, missing: [module3]", func() { + mm.SetOrderInitGenesis("module2", "module1") + }) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderExportGenesis) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderExportGenesis, missing: [module3]", func() { + mm.SetOrderExportGenesis("module2", "module1") + }) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderBeginBlockers) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderBeginBlockers, missing: [module2]", func() { + mm.SetOrderBeginBlockers("module1", "module3") + }) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderEndBlockers) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderEndBlockers, missing: [module1]", func() { + mm.SetOrderEndBlockers("module2", "module3") + }) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderPrecommiters) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderPrecommiters, missing: [module4]", func() { + mm.SetOrderPrecommiters("module2", "module1") + }) + + require.Equal(t, []string{"module1", "module2", "module3", "module4", "module5"}, mm.OrderPrepareCheckStaters) + require.PanicsWithValue(t, "all modules must be defined when setting SetOrderPrepareCheckStaters, missing: [module5]", func() { + mm.SetOrderPrepareCheckStaters("module2", "module1") + }) +} + func TestManagerOrderSetters(t *testing.T) { mockCtrl := gomock.NewController(t) t.Cleanup(mockCtrl.Finish) @@ -130,7 +184,7 @@ func TestManagerOrderSetters(t *testing.T) { require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters) - mm.SetOrderPepareCheckStaters("module3", "module2", "module1") + mm.SetOrderPrepareCheckStaters("module3", "module2", "module1") require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters) require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) @@ -473,6 +527,14 @@ func TestCoreAPIManagerOrderSetters(t *testing.T) { require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderEndBlockers) mm.SetOrderEndBlockers("module2", "module1", "module3") require.Equal(t, []string{"module2", "module1", "module3"}, mm.OrderEndBlockers) + + require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrepareCheckStaters) + mm.SetOrderPrepareCheckStaters("module3", "module2", "module1") + require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrepareCheckStaters) + + require.Equal(t, []string{"module1", "module2", "module3"}, mm.OrderPrecommiters) + mm.SetOrderPrecommiters("module3", "module2", "module1") + require.Equal(t, []string{"module3", "module2", "module1"}, mm.OrderPrecommiters) } func TestCoreAPIManager_BeginBlock(t *testing.T) { From b7dc52d416fad62367d5fbb6d47c6da9420aab8c Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 29 Mar 2023 16:45:54 -0400 Subject: [PATCH 10/16] Add new callbacks to config --- .../app/runtime/v1alpha1/module.pulsar.go | 348 ++++++++++++++++-- .../cosmos/app/runtime/v1alpha1/module.proto | 10 + runtime/app.go | 8 + 3 files changed, 330 insertions(+), 36 deletions(-) diff --git a/api/cosmos/app/runtime/v1alpha1/module.pulsar.go b/api/cosmos/app/runtime/v1alpha1/module.pulsar.go index e8fe74d59cd..d29da340c17 100644 --- a/api/cosmos/app/runtime/v1alpha1/module.pulsar.go +++ b/api/cosmos/app/runtime/v1alpha1/module.pulsar.go @@ -294,15 +294,109 @@ func (x *_Module_7_list) IsValid() bool { return x.list != nil } +var _ protoreflect.List = (*_Module_8_list)(nil) + +type _Module_8_list struct { + list *[]string +} + +func (x *_Module_8_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Module_8_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Module_8_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Module_8_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Module_8_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Module at list field Precommiters as it is not of Message kind")) +} + +func (x *_Module_8_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Module_8_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Module_8_list) IsValid() bool { + return x.list != nil +} + +var _ protoreflect.List = (*_Module_9_list)(nil) + +type _Module_9_list struct { + list *[]string +} + +func (x *_Module_9_list) Len() int { + if x.list == nil { + return 0 + } + return len(*x.list) +} + +func (x *_Module_9_list) Get(i int) protoreflect.Value { + return protoreflect.ValueOfString((*x.list)[i]) +} + +func (x *_Module_9_list) Set(i int, value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + (*x.list)[i] = concreteValue +} + +func (x *_Module_9_list) Append(value protoreflect.Value) { + valueUnwrapped := value.String() + concreteValue := valueUnwrapped + *x.list = append(*x.list, concreteValue) +} + +func (x *_Module_9_list) AppendMutable() protoreflect.Value { + panic(fmt.Errorf("AppendMutable can not be called on message Module at list field PrepareCheckStaters as it is not of Message kind")) +} + +func (x *_Module_9_list) Truncate(n int) { + *x.list = (*x.list)[:n] +} + +func (x *_Module_9_list) NewElement() protoreflect.Value { + v := "" + return protoreflect.ValueOfString(v) +} + +func (x *_Module_9_list) IsValid() bool { + return x.list != nil +} + var ( - md_Module protoreflect.MessageDescriptor - fd_Module_app_name protoreflect.FieldDescriptor - fd_Module_begin_blockers protoreflect.FieldDescriptor - fd_Module_end_blockers protoreflect.FieldDescriptor - fd_Module_init_genesis protoreflect.FieldDescriptor - fd_Module_export_genesis protoreflect.FieldDescriptor - fd_Module_override_store_keys protoreflect.FieldDescriptor - fd_Module_order_migrations protoreflect.FieldDescriptor + md_Module protoreflect.MessageDescriptor + fd_Module_app_name protoreflect.FieldDescriptor + fd_Module_begin_blockers protoreflect.FieldDescriptor + fd_Module_end_blockers protoreflect.FieldDescriptor + fd_Module_init_genesis protoreflect.FieldDescriptor + fd_Module_export_genesis protoreflect.FieldDescriptor + fd_Module_override_store_keys protoreflect.FieldDescriptor + fd_Module_order_migrations protoreflect.FieldDescriptor + fd_Module_precommiters protoreflect.FieldDescriptor + fd_Module_prepare_check_staters protoreflect.FieldDescriptor ) func init() { @@ -315,6 +409,8 @@ func init() { fd_Module_export_genesis = md_Module.Fields().ByName("export_genesis") fd_Module_override_store_keys = md_Module.Fields().ByName("override_store_keys") fd_Module_order_migrations = md_Module.Fields().ByName("order_migrations") + fd_Module_precommiters = md_Module.Fields().ByName("precommiters") + fd_Module_prepare_check_staters = md_Module.Fields().ByName("prepare_check_staters") } var _ protoreflect.Message = (*fastReflection_Module)(nil) @@ -424,6 +520,18 @@ func (x *fastReflection_Module) Range(f func(protoreflect.FieldDescriptor, proto return } } + if len(x.Precommiters) != 0 { + value := protoreflect.ValueOfList(&_Module_8_list{list: &x.Precommiters}) + if !f(fd_Module_precommiters, value) { + return + } + } + if len(x.PrepareCheckStaters) != 0 { + value := protoreflect.ValueOfList(&_Module_9_list{list: &x.PrepareCheckStaters}) + if !f(fd_Module_prepare_check_staters, value) { + return + } + } } // Has reports whether a field is populated. @@ -453,6 +561,10 @@ func (x *fastReflection_Module) Has(fd protoreflect.FieldDescriptor) bool { return len(x.OverrideStoreKeys) != 0 case "cosmos.app.runtime.v1alpha1.Module.order_migrations": return len(x.OrderMigrations) != 0 + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + return len(x.Precommiters) != 0 + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + return len(x.PrepareCheckStaters) != 0 default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module")) @@ -483,6 +595,10 @@ func (x *fastReflection_Module) Clear(fd protoreflect.FieldDescriptor) { x.OverrideStoreKeys = nil case "cosmos.app.runtime.v1alpha1.Module.order_migrations": x.OrderMigrations = nil + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + x.Precommiters = nil + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + x.PrepareCheckStaters = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module")) @@ -538,6 +654,18 @@ func (x *fastReflection_Module) Get(descriptor protoreflect.FieldDescriptor) pro } listValue := &_Module_7_list{list: &x.OrderMigrations} return protoreflect.ValueOfList(listValue) + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + if len(x.Precommiters) == 0 { + return protoreflect.ValueOfList(&_Module_8_list{}) + } + listValue := &_Module_8_list{list: &x.Precommiters} + return protoreflect.ValueOfList(listValue) + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + if len(x.PrepareCheckStaters) == 0 { + return protoreflect.ValueOfList(&_Module_9_list{}) + } + listValue := &_Module_9_list{list: &x.PrepareCheckStaters} + return protoreflect.ValueOfList(listValue) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module")) @@ -584,6 +712,14 @@ func (x *fastReflection_Module) Set(fd protoreflect.FieldDescriptor, value proto lv := value.List() clv := lv.(*_Module_7_list) x.OrderMigrations = *clv.list + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + lv := value.List() + clv := lv.(*_Module_8_list) + x.Precommiters = *clv.list + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + lv := value.List() + clv := lv.(*_Module_9_list) + x.PrepareCheckStaters = *clv.list default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module")) @@ -640,6 +776,18 @@ func (x *fastReflection_Module) Mutable(fd protoreflect.FieldDescriptor) protore } value := &_Module_7_list{list: &x.OrderMigrations} return protoreflect.ValueOfList(value) + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + if x.Precommiters == nil { + x.Precommiters = []string{} + } + value := &_Module_8_list{list: &x.Precommiters} + return protoreflect.ValueOfList(value) + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + if x.PrepareCheckStaters == nil { + x.PrepareCheckStaters = []string{} + } + value := &_Module_9_list{list: &x.PrepareCheckStaters} + return protoreflect.ValueOfList(value) case "cosmos.app.runtime.v1alpha1.Module.app_name": panic(fmt.Errorf("field app_name of message cosmos.app.runtime.v1alpha1.Module is not mutable")) default: @@ -675,6 +823,12 @@ func (x *fastReflection_Module) NewField(fd protoreflect.FieldDescriptor) protor case "cosmos.app.runtime.v1alpha1.Module.order_migrations": list := []string{} return protoreflect.ValueOfList(&_Module_7_list{list: &list}) + case "cosmos.app.runtime.v1alpha1.Module.precommiters": + list := []string{} + return protoreflect.ValueOfList(&_Module_8_list{list: &list}) + case "cosmos.app.runtime.v1alpha1.Module.prepare_check_staters": + list := []string{} + return protoreflect.ValueOfList(&_Module_9_list{list: &list}) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: cosmos.app.runtime.v1alpha1.Module")) @@ -784,6 +938,18 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { n += 1 + l + runtime.Sov(uint64(l)) } } + if len(x.Precommiters) > 0 { + for _, s := range x.Precommiters { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } + if len(x.PrepareCheckStaters) > 0 { + for _, s := range x.PrepareCheckStaters { + l = len(s) + n += 1 + l + runtime.Sov(uint64(l)) + } + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -813,6 +979,24 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if len(x.PrepareCheckStaters) > 0 { + for iNdEx := len(x.PrepareCheckStaters) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.PrepareCheckStaters[iNdEx]) + copy(dAtA[i:], x.PrepareCheckStaters[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.PrepareCheckStaters[iNdEx]))) + i-- + dAtA[i] = 0x4a + } + } + if len(x.Precommiters) > 0 { + for iNdEx := len(x.Precommiters) - 1; iNdEx >= 0; iNdEx-- { + i -= len(x.Precommiters[iNdEx]) + copy(dAtA[i:], x.Precommiters[iNdEx]) + i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Precommiters[iNdEx]))) + i-- + dAtA[i] = 0x42 + } + } if len(x.OrderMigrations) > 0 { for iNdEx := len(x.OrderMigrations) - 1; iNdEx >= 0; iNdEx-- { i -= len(x.OrderMigrations[iNdEx]) @@ -1156,6 +1340,70 @@ func (x *fastReflection_Module) ProtoMethods() *protoiface.Methods { } x.OrderMigrations = append(x.OrderMigrations, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex + case 8: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Precommiters", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.Precommiters = append(x.Precommiters, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 9: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field PrepareCheckStaters", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + x.PrepareCheckStaters = append(x.PrepareCheckStaters, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -1719,6 +1967,14 @@ type Module struct { // If this is left empty, it uses the default migration order. // https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.47.0-alpha2/types/module#DefaultMigrationsOrder OrderMigrations []string `protobuf:"bytes,7,rep,name=order_migrations,json=orderMigrations,proto3" json:"order_migrations,omitempty"` + // precommiters specifies the module names of the precommiters + // to call in the order in which they should be called. If this is left empty + // no precommit function will be registered. + Precommiters []string `protobuf:"bytes,8,rep,name=precommiters,proto3" json:"precommiters,omitempty"` + // prepare_check_staters specifies the module names of the prepare_check_staters + // to call in the order in which they should be called. If this is left empty + // no preparecheckstate function will be registered. + PrepareCheckStaters []string `protobuf:"bytes,9,rep,name=prepare_check_staters,json=prepareCheckStaters,proto3" json:"prepare_check_staters,omitempty"` } func (x *Module) Reset() { @@ -1790,6 +2046,20 @@ func (x *Module) GetOrderMigrations() []string { return nil } +func (x *Module) GetPrecommiters() []string { + if x != nil { + return x.Precommiters + } + return nil +} + +func (x *Module) GetPrepareCheckStaters() []string { + if x != nil { + return x.PrepareCheckStaters + } + return nil +} + // StoreKeyConfig may be supplied to override the default module store key, which // is the module name. type StoreKeyConfig struct { @@ -1846,7 +2116,7 @@ var file_cosmos_app_runtime_v1alpha1_module_proto_rawDesc = []byte{ 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x20, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6d, 0x6f, 0x64, - 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x84, 0x03, 0x0a, 0x06, 0x4d, 0x6f, + 0x75, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, 0x03, 0x0a, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x61, 0x70, 0x70, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x62, 0x65, 0x67, 0x69, 0x6e, 0x5f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x72, @@ -1866,33 +2136,39 @@ var file_cosmos_app_runtime_v1alpha1_module_proto_rawDesc = []byte{ 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x72, 0x64, 0x65, - 0x72, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3a, 0x43, 0xba, 0xc0, 0x96, - 0xda, 0x01, 0x3d, 0x0a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, - 0x6b, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x15, 0x0a, 0x13, 0x63, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, - 0x22, 0x53, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x6b, 0x76, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6b, 0x76, 0x53, 0x74, 0x6f, - 0x72, 0x65, 0x4b, 0x65, 0x79, 0x42, 0xfb, 0x01, 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x41, 0x52, 0xaa, 0x02, 0x1b, 0x43, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, 0x70, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, - 0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, 0x02, 0x1b, 0x43, 0x6f, 0x73, - 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, - 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xe2, 0x02, 0x27, 0x43, 0x6f, 0x73, 0x6d, 0x6f, - 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x1e, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x70, - 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x70, + 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0c, 0x70, 0x72, 0x65, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x65, 0x72, 0x73, 0x12, + 0x32, 0x0a, 0x15, 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13, + 0x70, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x72, 0x73, 0x3a, 0x43, 0xba, 0xc0, 0x96, 0xda, 0x01, 0x3d, 0x0a, 0x24, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x12, 0x15, 0x0a, 0x13, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, 0x2e, + 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x53, 0x0a, 0x0e, 0x53, 0x74, 0x6f, 0x72, + 0x65, 0x4b, 0x65, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0c, 0x6b, + 0x76, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x6b, 0x76, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x4b, 0x65, 0x79, 0x42, 0xfb, 0x01, + 0x0a, 0x1f, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x70, + 0x2e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, + 0x31, 0x42, 0x0b, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x3c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, + 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, + 0x03, 0x43, 0x41, 0x52, 0xaa, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x70, + 0x70, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, + 0x61, 0x31, 0xca, 0x02, 0x1b, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, + 0xe2, 0x02, 0x27, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x41, 0x70, 0x70, 0x5c, 0x52, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, + 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x1e, 0x43, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x41, 0x70, 0x70, 0x3a, 0x3a, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, + 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/proto/cosmos/app/runtime/v1alpha1/module.proto b/proto/cosmos/app/runtime/v1alpha1/module.proto index e92ce482f3f..c0261217027 100644 --- a/proto/cosmos/app/runtime/v1alpha1/module.proto +++ b/proto/cosmos/app/runtime/v1alpha1/module.proto @@ -42,6 +42,16 @@ message Module { // If this is left empty, it uses the default migration order. // https://pkg.go.dev/github.com/cosmos/cosmos-sdk@v0.47.0-alpha2/types/module#DefaultMigrationsOrder repeated string order_migrations = 7; + + // precommiters specifies the module names of the precommiters + // to call in the order in which they should be called. If this is left empty + // no precommit function will be registered. + repeated string precommiters = 8; + + // prepare_check_staters specifies the module names of the prepare_check_staters + // to call in the order in which they should be called. If this is left empty + // no preparecheckstate function will be registered. + repeated string prepare_check_staters = 9; } // StoreKeyConfig may be supplied to override the default module store key, which diff --git a/runtime/app.go b/runtime/app.go index 7388ec9faa2..ee85f56277d 100644 --- a/runtime/app.go +++ b/runtime/app.go @@ -102,6 +102,14 @@ func (a *App) Load(loadLatest bool) error { a.SetEndBlocker(a.EndBlocker) } + if len(a.config.Precommiters) != 0 { + a.ModuleManager.SetOrderPrecommiters(a.config.Precommiters...) + } + + if len(a.config.PrepareCheckStaters) != 0 { + a.ModuleManager.SetOrderPrepareCheckStaters(a.config.PrepareCheckStaters...) + } + if len(a.config.OrderMigrations) != 0 { a.ModuleManager.SetOrderMigrations(a.config.OrderMigrations...) } From eb40e33107b71dcd0f02f73cd8a3fc147c343bb2 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 29 Mar 2023 17:34:07 -0400 Subject: [PATCH 11/16] Update mod file with api --- go.mod | 1 + go.sum | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 01f48586467..68a4cc006ca 100644 --- a/go.mod +++ b/go.mod @@ -160,6 +160,7 @@ require ( // Below are the long-lived replace of the Cosmos SDK replace ( + cosmossdk.io/api => ./api // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 // dgrijalva/jwt-go is deprecated and doesn't receive security updates. diff --git a/go.sum b/go.sum index 1f5fcb69c8d..61ca163f18b 100644 --- a/go.sum +++ b/go.sum @@ -35,8 +35,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -cosmossdk.io/api v0.3.2-0.20230313131911-55bf5d4efbe7 h1:4LrWK+uGP5IxznxtHHsHD+ZBs2+oZRH2loYOGjHLzZM= -cosmossdk.io/api v0.3.2-0.20230313131911-55bf5d4efbe7/go.mod h1:yVns7mKgcsG+hZW/3C5FdJtC6QYWdFIcRlKb9+5HV5g= cosmossdk.io/collections v0.0.0-20230309163709-87da587416ba h1:S4PYij/tX3Op/hwenVEN9D+M27JRcwSwVqE3UA0BnwM= cosmossdk.io/collections v0.0.0-20230309163709-87da587416ba/go.mod h1:lpS+G8bGC2anqzWdndTzjnQnuMO/qAcgZUkGJp4i3rc= cosmossdk.io/core v0.6.1 h1:OBy7TI2W+/gyn2z40vVvruK3di+cAluinA6cybFbE7s= From ea68fee2de6621879c53e5cc74987db2584a2be7 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Thu, 30 Mar 2023 11:45:15 -0400 Subject: [PATCH 12/16] Update NewManagerFromMap --- types/module/module.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/types/module/module.go b/types/module/module.go index ba3b5ce545b..9ed83c97be0 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -310,11 +310,13 @@ func NewManagerFromMap(moduleMap map[string]appmodule.AppModule) *Manager { sort.Strings(modulesStr) return &Manager{ - Modules: simpleModuleMap, - OrderInitGenesis: modulesStr, - OrderExportGenesis: modulesStr, - OrderBeginBlockers: modulesStr, - OrderEndBlockers: modulesStr, + Modules: simpleModuleMap, + OrderInitGenesis: modulesStr, + OrderExportGenesis: modulesStr, + OrderBeginBlockers: modulesStr, + OrderEndBlockers: modulesStr, + OrderPrecommiters: modulesStr, + OrderPrepareCheckStaters: modulesStr, } } From a0616d01acf91c911948742a2a6da8400850b24d Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Thu, 30 Mar 2023 12:08:09 -0400 Subject: [PATCH 13/16] Add api to tests package go.mod --- tests/go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/go.mod b/tests/go.mod index 295ce60794f..97071c98d9d 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -191,6 +191,7 @@ require ( // It must be in sync with SimApp temporary replaces replace ( // TODO tag all extracted modules after SDK refactor + cosmossdk.io/api => ./api cosmossdk.io/store => ../store cosmossdk.io/x/evidence => ../x/evidence cosmossdk.io/x/feegrant => ../x/feegrant From 5393018003d2d0ad17efe330a7a5f0b19edb72b5 Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Thu, 30 Mar 2023 12:52:44 -0400 Subject: [PATCH 14/16] Add api to tests package go.mod --- tests/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/go.mod b/tests/go.mod index 97071c98d9d..6d3e97fd5fe 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -191,7 +191,7 @@ require ( // It must be in sync with SimApp temporary replaces replace ( // TODO tag all extracted modules after SDK refactor - cosmossdk.io/api => ./api + cosmossdk.io/api => ../api cosmossdk.io/store => ../store cosmossdk.io/x/evidence => ../x/evidence cosmossdk.io/x/feegrant => ../x/feegrant From f20ee96ad3976a8c8a6d3f090f0b73cf51efe75f Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 5 Apr 2023 08:26:47 -0400 Subject: [PATCH 15/16] Set callbacks during Load --- baseapp/abci_test.go | 4 ++-- baseapp/baseapp_test.go | 2 +- baseapp/options.go | 4 ++-- runtime/app.go | 12 ++++++++++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/baseapp/abci_test.go b/baseapp/abci_test.go index 3cf8ac951e9..d317026c9c5 100644 --- a/baseapp/abci_test.go +++ b/baseapp/abci_test.go @@ -616,7 +616,7 @@ func TestBaseApp_PrepareCheckState(t *testing.T) { }) wasPrepareCheckStateCalled := false - app.SetPrepareCheckState(func(ctx sdk.Context) { + app.SetPrepareCheckStater(func(ctx sdk.Context) { wasPrepareCheckStateCalled = true }) app.Seal() @@ -1386,7 +1386,7 @@ func TestPrepareCheckStateCalledWithCheckState(t *testing.T) { app := baseapp.NewBaseApp(name, logger, db, nil) wasPrepareCheckStateCalled := false - app.SetPrepareCheckState(func(ctx sdk.Context) { + app.SetPrepareCheckStater(func(ctx sdk.Context) { require.Equal(t, true, ctx.IsCheckTx()) wasPrepareCheckStateCalled = true }) diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 18ff0b65bb5..f5fe99d1088 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -389,7 +389,7 @@ func TestBaseAppOptionSeal(t *testing.T) { suite.baseApp.SetEndBlocker(nil) }) require.Panics(t, func() { - suite.baseApp.SetPrepareCheckState(nil) + suite.baseApp.SetPrepareCheckStater(nil) }) require.Panics(t, func() { suite.baseApp.SetPrecommiter(nil) diff --git a/baseapp/options.go b/baseapp/options.go index d227a3d1f0e..c30488df4ee 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -167,9 +167,9 @@ func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { app.endBlocker = endBlocker } -func (app *BaseApp) SetPrepareCheckState(prepareCheckStater sdk.PrepareCheckStater) { +func (app *BaseApp) SetPrepareCheckStater(prepareCheckStater sdk.PrepareCheckStater) { if app.sealed { - panic("SetPrepareCheckState() on sealed BaseApp") + panic("SetPrepareCheckStater() on sealed BaseApp") } app.prepareCheckStater = prepareCheckStater diff --git a/runtime/app.go b/runtime/app.go index ee85f56277d..781b885258e 100644 --- a/runtime/app.go +++ b/runtime/app.go @@ -104,10 +104,12 @@ func (a *App) Load(loadLatest bool) error { if len(a.config.Precommiters) != 0 { a.ModuleManager.SetOrderPrecommiters(a.config.Precommiters...) + a.SetPrecommiter(a.Precommiter) } if len(a.config.PrepareCheckStaters) != 0 { a.ModuleManager.SetOrderPrepareCheckStaters(a.config.PrepareCheckStaters...) + a.SetPrepareCheckStater(a.PrepareCheckStater) } if len(a.config.OrderMigrations) != 0 { @@ -133,6 +135,16 @@ func (a *App) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) (abci.Respon return a.ModuleManager.EndBlock(ctx, req) } +// Precommiter application updates every commit +func (a *App) Precommiter(ctx sdk.Context) { + a.ModuleManager.Precommit(ctx) +} + +// PrepareCheckStater application updates every commit +func (a *App) PrepareCheckStater(ctx sdk.Context) { + a.ModuleManager.PrepareCheckState(ctx) +} + // InitChainer initializes the chain. func (a *App) InitChainer(ctx sdk.Context, req abci.RequestInitChain) (abci.ResponseInitChain, error) { var genesisState map[string]json.RawMessage From cf4674e570f964ef10c36c1bc6c9f7c6f0e0f3dd Mon Sep 17 00:00:00 2001 From: Bryce Neal Date: Wed, 5 Apr 2023 08:30:20 -0400 Subject: [PATCH 16/16] Fix comment --- types/module/module.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/types/module/module.go b/types/module/module.go index 9ed83c97be0..120a808b09a 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -370,7 +370,7 @@ func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.OrderEndBlockers = moduleNames } -// SetOrderPrepareCheckStaters sets the order of set commiter calls +// SetOrderPrepareCheckStaters sets the order of set prepare-check-stater calls func (m *Manager) SetOrderPrepareCheckStaters(moduleNames ...string) { m.assertNoForgottenModules("SetOrderPrepareCheckStaters", moduleNames, func(moduleName string) bool { @@ -747,25 +747,25 @@ func (m *Manager) EndBlock(ctx sdk.Context, req abci.RequestEndBlock) (abci.Resp }, nil } -// PrepareCheckState performs functionality for preparing the check state for all modules. -func (m *Manager) PrepareCheckState(ctx sdk.Context) { - for _, moduleName := range m.OrderPrepareCheckStaters { - module, ok := m.Modules[moduleName].(PrepareCheckStateAppModule) +// Precommit performs precommit functionality for all modules. +func (m *Manager) Precommit(ctx sdk.Context) { + for _, moduleName := range m.OrderPrecommiters { + module, ok := m.Modules[moduleName].(PrecommitAppModule) if !ok { continue } - module.PrepareCheckState(ctx) + module.Precommit(ctx) } } -// Precommit performs precommit functionality for all modules. -func (m *Manager) Precommit(ctx sdk.Context) { - for _, moduleName := range m.OrderPrecommiters { - module, ok := m.Modules[moduleName].(PrecommitAppModule) +// PrepareCheckState performs functionality for preparing the check state for all modules. +func (m *Manager) PrepareCheckState(ctx sdk.Context) { + for _, moduleName := range m.OrderPrepareCheckStaters { + module, ok := m.Modules[moduleName].(PrepareCheckStateAppModule) if !ok { continue } - module.Precommit(ctx) + module.PrepareCheckState(ctx) } }