From c86299bcf2a00e4b79402f9bef78dc5f42f653d9 Mon Sep 17 00:00:00 2001 From: crypin Date: Thu, 8 Jun 2023 17:52:26 +0900 Subject: [PATCH] feat!: add MidBlock interface on ABCI, bump tendermint to MidBlock applied --- baseapp/abci.go | 7 +++++++ baseapp/baseapp.go | 7 ++++--- baseapp/deliver_tx_test.go | 2 +- baseapp/options.go | 8 ++++++++ go.mod | 2 ++ go.sum | 4 ++-- simapp/app.go | 7 +++++++ simapp/types.go | 2 ++ types/abci.go | 2 ++ types/module/module.go | 29 +++++++++++++++++++++++++++++ types/module/module_test.go | 6 ++++++ 11 files changed, 70 insertions(+), 6 deletions(-) diff --git a/baseapp/abci.go b/baseapp/abci.go index b934255da462..30cbe2dadcb6 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -190,6 +190,13 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg return res } +func (app *BaseApp) MidBlock(req abci.RequestMidBlock) (res abci.ResponseMidBlock) { + if app.midBlocker != nil { + return app.midBlocker(app.deliverState.ctx, req) + } + return abci.ResponseMidBlock{} +} + // EndBlock implements the ABCI interface. func (app *BaseApp) EndBlock(req abci.RequestEndBlock) (res abci.ResponseEndBlock) { defer telemetry.MeasureSince(time.Now(), "abci", "end_block") diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index b51f7805bdf9..b9be483f44a3 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -48,7 +48,7 @@ type BaseApp struct { //nolint: maligned logger log.Logger name string // application name from abci.Info interfaceRegistry types.InterfaceRegistry - txDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx + TxDecoder sdk.TxDecoder // unmarshal []byte into sdk.Tx anteHandler sdk.AnteHandler // ante handler for fee and auth @@ -134,6 +134,7 @@ type moduleRouter struct { type abciData struct { initChainer sdk.InitChainer // initialize state with validators and state blob beginBlocker sdk.BeginBlocker // logic to run before any txs + midBlocker sdk.MidBlocker // logic to run before any txs after begin block endBlocker sdk.EndBlocker // logic to run after all txs, and to determine valset changes // absent validators from begin block @@ -181,7 +182,7 @@ func NewBaseApp( grpcQueryRouter: NewGRPCQueryRouter(), msgServiceRouter: NewMsgServiceRouter(), }, - txDecoder: txDecoder, + TxDecoder: txDecoder, } for _, option := range options { @@ -656,7 +657,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte) (gInfo sdk.GasInfo, re defer consumeBlockGas() } - tx, err := app.txDecoder(txBytes) + tx, err := app.TxDecoder(txBytes) if err != nil { return sdk.GasInfo{}, nil, nil, err } diff --git a/baseapp/deliver_tx_test.go b/baseapp/deliver_tx_test.go index c0126f9964f4..586efc25190e 100644 --- a/baseapp/deliver_tx_test.go +++ b/baseapp/deliver_tx_test.go @@ -1501,7 +1501,7 @@ func TestTxDecoder(t *testing.T) { tx := newTxCounter(1, 0) txBytes := codec.MustMarshal(tx) - dTx, err := app.txDecoder(txBytes) + dTx, err := app.TxDecoder(txBytes) require.NoError(t, err) cTx := dTx.(txTest) diff --git a/baseapp/options.go b/baseapp/options.go index 53d4a4b11c76..e75195dc3e15 100644 --- a/baseapp/options.go +++ b/baseapp/options.go @@ -150,6 +150,14 @@ func (app *BaseApp) SetBeginBlocker(beginBlocker sdk.BeginBlocker) { app.beginBlocker = beginBlocker } +func (app *BaseApp) SetMidBlocker(midBlocker sdk.MidBlocker) { + if app.sealed { + panic("SetMidBlocker() on sealed BaseApp") + } + + app.midBlocker = midBlocker +} + func (app *BaseApp) SetEndBlocker(endBlocker sdk.EndBlocker) { if app.sealed { panic("SetEndBlocker() on sealed BaseApp") diff --git a/go.mod b/go.mod index c36e4a74cb85..c4c04453e38c 100644 --- a/go.mod +++ b/go.mod @@ -138,6 +138,8 @@ replace ( github.com/jhump/protoreflect => github.com/jhump/protoreflect v1.9.0 + github.com/tendermint/tendermint => github.com/crescent-network/tendermint v0.34.22-mid-block-1 + // latest grpc doesn't work with with our modified proto compiler, so we need to enforce // the following version across all dependencies. google.golang.org/grpc => google.golang.org/grpc v1.33.2 diff --git a/go.sum b/go.sum index 08be076135a9..4a4e51c9d219 100644 --- a/go.sum +++ b/go.sum @@ -172,6 +172,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creachadair/taskgroup v0.3.2 h1:zlfutDS+5XG40AOxcHDSThxKzns8Tnr9jnr6VqkYlkM= github.com/creachadair/taskgroup v0.3.2/go.mod h1:wieWwecHVzsidg2CsUnFinW1faVN4+kq+TDlRJQ0Wbk= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/crescent-network/tendermint v0.34.22-mid-block-1 h1:u3u6hcEEZxoMQTviFrmNfmkmr2jStlhEuy2EeNJcIg4= +github.com/crescent-network/tendermint v0.34.22-mid-block-1/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -749,8 +751,6 @@ github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 h1:hqAk8riJvK4RM github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk= github.com/tendermint/go-amino v0.16.0 h1:GyhmgQKvqF82e2oZeuMSp9JTN0N09emoSZlb2lyGa2E= github.com/tendermint/go-amino v0.16.0/go.mod h1:TQU0M1i/ImAo+tYpZi73AU3V/dKeCoMC9Sphe2ZwGME= -github.com/tendermint/tendermint v0.34.22 h1:XMhtC8s8QqJO4l/dn+TkQvevTRSow3Vixjclr41o+2Q= -github.com/tendermint/tendermint v0.34.22/go.mod h1:YpP5vBEAKUT4g6oyfjKgFeZmdB/GjkJAxfF+cgmJg6Y= github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM= github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= diff --git a/simapp/app.go b/simapp/app.go index 955f9f41b610..735a05661274 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -343,6 +343,7 @@ func NewSimApp( authz.ModuleName, feegrant.ModuleName, paramstypes.ModuleName, vestingtypes.ModuleName, ) + app.mm.SetOrderMidBlockers() app.mm.SetOrderEndBlockers( crisistypes.ModuleName, govtypes.ModuleName, stakingtypes.ModuleName, capabilitytypes.ModuleName, authtypes.ModuleName, banktypes.ModuleName, distrtypes.ModuleName, @@ -395,6 +396,7 @@ func NewSimApp( // initialize BaseApp app.SetInitChainer(app.InitChainer) app.SetBeginBlocker(app.BeginBlocker) + app.SetMidBlocker(app.MidBlocker) anteHandler, err := ante.NewAnteHandler( ante.HandlerOptions{ @@ -429,6 +431,11 @@ func (app *SimApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abc return app.mm.BeginBlock(ctx, req) } +func (app *SimApp) MidBlocker(ctx sdk.Context, req abci.RequestMidBlock) abci.ResponseMidBlock { + events := app.mm.MidBlock(ctx) + return abci.ResponseMidBlock{Events: events} +} + // EndBlocker application updates every end block func (app *SimApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { return app.mm.EndBlock(ctx, req) diff --git a/simapp/types.go b/simapp/types.go index 0e190af1bc93..6f01b22fc033 100644 --- a/simapp/types.go +++ b/simapp/types.go @@ -22,6 +22,8 @@ type App interface { // Application updates every begin block. BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock + MidBlocker(ctx sdk.Context, req abci.RequestMidBlock) abci.ResponseMidBlock + // Application updates every end block. EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock diff --git a/types/abci.go b/types/abci.go index 8f71362eda6d..27e3f3c307f9 100644 --- a/types/abci.go +++ b/types/abci.go @@ -11,6 +11,8 @@ type InitChainer func(ctx Context, req abci.RequestInitChain) abci.ResponseInitC // e.g. BFT timestamps rather than block height for any periodic BeginBlock logic type BeginBlocker func(ctx Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock +type MidBlocker func(ctx Context, req abci.RequestMidBlock) abci.ResponseMidBlock + // EndBlocker runs code after the transactions in a block and return updates to the validator set // // Note: applications which set create_empty_blocks=false will not have regular block timing and should use diff --git a/types/module/module.go b/types/module/module.go index 795553e78c8f..7b4242394c76 100644 --- a/types/module/module.go +++ b/types/module/module.go @@ -186,6 +186,12 @@ type BeginBlockAppModule interface { BeginBlock(sdk.Context, abci.RequestBeginBlock) } +// MidBlockAppModule is an extension interface that contains information about the AppModule and BeginBlock. +type MidBlockAppModule interface { + AppModule + MidBlock(sdk.Context) +} + // EndBlockAppModule is an extension interface that contains information about the AppModule and EndBlock. type EndBlockAppModule interface { AppModule @@ -237,6 +243,7 @@ type Manager struct { OrderInitGenesis []string OrderExportGenesis []string OrderBeginBlockers []string + OrderMidBlockers []string OrderEndBlockers []string OrderMigrations []string } @@ -255,6 +262,7 @@ func NewManager(modules ...AppModule) *Manager { OrderInitGenesis: modulesStr, OrderExportGenesis: modulesStr, OrderBeginBlockers: modulesStr, + OrderMidBlockers: modulesStr, OrderEndBlockers: modulesStr, } } @@ -277,6 +285,11 @@ func (m *Manager) SetOrderBeginBlockers(moduleNames ...string) { m.OrderBeginBlockers = moduleNames } +// SetOrderMidBlockers sets the order of set mid-blocker calls +func (m *Manager) SetOrderMidBlockers(moduleNames ...string) { + m.OrderMidBlockers = moduleNames +} + // SetOrderEndBlockers sets the order of set end-blocker calls func (m *Manager) SetOrderEndBlockers(moduleNames ...string) { m.assertNoForgottenModules("SetOrderEndBlockers", moduleNames) @@ -497,6 +510,22 @@ func (m *Manager) BeginBlock(ctx sdk.Context, req abci.RequestBeginBlock) abci.R } } +// MidBlock performs mid block functionality for all modules. It creates a +// child context with an event manager to aggregate events emitted from all +// modules. +func (m *Manager) MidBlock(ctx sdk.Context) []abci.Event { + ctx = ctx.WithEventManager(sdk.NewEventManager()) + + for _, moduleName := range m.OrderMidBlockers { + module, ok := m.Modules[moduleName].(MidBlockAppModule) + if ok { + module.MidBlock(ctx) + } + } + + return ctx.EventManager().ABCIEvents() +} + // EndBlock performs end block functionality for all modules. It creates a // child context with an event manager to aggregate events emitted from all // modules. diff --git a/types/module/module_test.go b/types/module/module_test.go index 7e880b4b1003..42d6ff8ccbf4 100644 --- a/types/module/module_test.go +++ b/types/module/module_test.go @@ -111,6 +111,12 @@ func TestManagerOrderSetters(t *testing.T) { require.Equal(t, []string{"module1", "module2"}, mm.OrderEndBlockers) mm.SetOrderEndBlockers("module2", "module1") require.Equal(t, []string{"module2", "module1"}, mm.OrderEndBlockers) + + require.Equal(t, []string{"module1", "module2"}, mm.OrderMidBlockers) + mm.SetOrderMidBlockers("module2", "module1") + require.Equal(t, []string{"module2", "module1"}, mm.OrderMidBlockers) + mm.SetOrderMidBlockers("module1") + require.Equal(t, []string{"module1"}, mm.OrderMidBlockers) } func TestManager_RegisterInvariants(t *testing.T) {