From 6be78713b74898e7109085ee5d88488e70aad372 Mon Sep 17 00:00:00 2001 From: Eric Warehime Date: Tue, 19 Dec 2023 17:09:08 -0800 Subject: [PATCH] fix(baseapp): Reset GasMeter before deliverTX v0.47.x backport (#18826) --- CHANGELOG.md | 1 + baseapp/abci.go | 4 ++++ baseapp/baseapp_test.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9195332f0f9a..5db27ee1fff6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (baseapp) [#18609](https://github.com/cosmos/cosmos-sdk/issues/18609) Fixed accounting in the block gas meter after BeginBlock and before DeliverTx, ensuring transaction processing always starts with the expected zeroed out block gas meter. * (server) [#18537](https://github.com/cosmos/cosmos-sdk/pull/18537) Fix panic when defining minimum gas config as `100stake;100uatom`. Use a `,` delimiter instead of `;`. Fixes the server config getter to use the correct delimiter. * (client/tx) [#18472](https://github.com/cosmos/cosmos-sdk/pull/18472) Utilizes the correct Pubkey when simulating a transaction. diff --git a/baseapp/abci.go b/baseapp/abci.go index 32a6d8683227..08dbe8d367b9 100644 --- a/baseapp/abci.go +++ b/baseapp/abci.go @@ -206,6 +206,10 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg } } + // Reset the gas meter so that the AnteHandlers aren't required to + gasMeter = app.getBlockGasMeter(app.deliverState.ctx) + app.deliverState.ctx = app.deliverState.ctx.WithBlockGasMeter(gasMeter) + return res } diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 84614a9a6f5f..c278d7cf85e7 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -158,6 +158,41 @@ func NewBaseAppSuiteWithSnapshots(t *testing.T, cfg SnapshotsConfig, opts ...fun return suite } +func TestAnteHandlerGasMeter(t *testing.T) { + // run BeginBlock and assert that the gas meter passed into the first Txn's AnteHandlers is zeroed out + anteOpt := func(bapp *baseapp.BaseApp) { + bapp.SetAnteHandler(func(ctx sdk.Context, tx sdk.Tx, simulate bool) (newCtx sdk.Context, err error) { + gasMeter := ctx.BlockGasMeter() + require.NotNil(t, gasMeter) + require.Equal(t, sdk.Gas(0), gasMeter.GasConsumed()) + return ctx, nil + }) + } + // set the beginBlocker to use some gas + beginBlockerOpt := func(bapp *baseapp.BaseApp) { + bapp.SetBeginBlocker(func(ctx sdk.Context, req abci.RequestBeginBlock) abci.ResponseBeginBlock { + ctx.BlockGasMeter().ConsumeGas(1, "beginBlocker gas consumption") + return abci.ResponseBeginBlock{} + }) + } + + suite := NewBaseAppSuite(t, anteOpt, beginBlockerOpt) + + _ = suite.baseApp.InitChain(abci.RequestInitChain{ + ConsensusParams: &tmproto.ConsensusParams{}, + }) + + // Run BeginBlock to consume some gas + header := tmproto.Header{Height: 1} + suite.baseApp.BeginBlock(abci.RequestBeginBlock{Header: header}) + + // Run our first Tx (make sure the AnteHandler doesn't see gas consumed in BeginBlock + tx := newTxCounter(t, suite.txConfig, 0, 0) + txBytes, err := suite.txConfig.TxEncoder()(tx) + require.NoError(t, err) + suite.baseApp.DeliverTx(abci.RequestDeliverTx{Tx: txBytes}) +} + func TestLoadVersion(t *testing.T) { logger := defaultLogger() pruningOpt := baseapp.SetPruning(pruningtypes.NewPruningOptions(pruningtypes.PruningNothing))