fix(baseapp): nil check in posthandler events (#19058)

This commit is contained in:
Julien Robert 2024-01-15 18:08:31 +01:00 committed by GitHub
parent 1752e0cc3d
commit 73c074117f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 11 deletions

View File

@ -80,6 +80,7 @@ Every Module contains its own CHANGELOG.md. Please refer to the module you are i
### Bug Fixes
* (baseapp) [#19058](https://github.com/cosmos/cosmos-sdk/pull/19058) Fix baseapp posthandler branch would fail if the `runMsgs` had returned an error.
* (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.
* (baseapp) [#18727](https://github.com/cosmos/cosmos-sdk/pull/18727) Ensure that `BaseApp.Init` firstly returns any errors from a nil commit multistore instead of panicking on nil dereferencing and before sealing the app.
* (client) [#18622](https://github.com/cosmos/cosmos-sdk/pull/18622) Fixed a potential under/overflow from `uint64->int64` when computing gas fees as a LegacyDec.

View File

@ -944,11 +944,15 @@ func (app *BaseApp) runTx(mode execMode, txBytes []byte) (gInfo sdk.GasInfo, res
// Note that the state is still preserved.
postCtx := runMsgCtx.WithEventManager(sdk.NewEventManager())
newCtx, err := app.postHandler(postCtx, tx, mode == execModeSimulate, err == nil)
if err != nil {
return gInfo, nil, anteEvents, err
newCtx, errPostHandler := app.postHandler(postCtx, tx, mode == execModeSimulate, err == nil)
if errPostHandler != nil {
return gInfo, nil, anteEvents, errors.Join(err, errPostHandler)
}
// we don't want runTx to panic if runMsgs has failed earlier
if result == nil {
result = &sdk.Result{}
}
result.Events = append(result.Events, newCtx.EventManager().ABCIEvents()...)
}

View File

@ -1,6 +1,7 @@
package baseapp_test
import (
"bytes"
"context"
"crypto/sha256"
"fmt"
@ -45,9 +46,10 @@ var (
type (
BaseAppSuite struct {
baseApp *baseapp.BaseApp
cdc *codec.ProtoCodec
txConfig client.TxConfig
baseApp *baseapp.BaseApp
cdc *codec.ProtoCodec
txConfig client.TxConfig
logBuffer *bytes.Buffer
}
SnapshotsConfig struct {
@ -66,8 +68,10 @@ func NewBaseAppSuite(t *testing.T, opts ...func(*baseapp.BaseApp)) *BaseAppSuite
txConfig := authtx.NewTxConfig(cdc, authtx.DefaultSignModes)
db := dbm.NewMemDB()
logBuffer := new(bytes.Buffer)
logger := log.NewLogger(logBuffer, log.ColorOption(false))
app := baseapp.NewBaseApp(t.Name(), log.NewTestLogger(t), db, txConfig.TxDecoder(), opts...)
app := baseapp.NewBaseApp(t.Name(), logger, db, txConfig.TxDecoder(), opts...)
require.Equal(t, t.Name(), app.Name())
app.SetInterfaceRegistry(cdc.InterfaceRegistry())
@ -81,9 +85,10 @@ func NewBaseAppSuite(t *testing.T, opts ...func(*baseapp.BaseApp)) *BaseAppSuite
require.Nil(t, app.LoadLatestVersion())
return &BaseAppSuite{
baseApp: app,
cdc: cdc,
txConfig: txConfig,
baseApp: app,
cdc: cdc,
txConfig: txConfig,
logBuffer: logBuffer,
}
}
@ -638,7 +643,6 @@ func TestBaseAppPostHandler(t *testing.T) {
}
suite := NewBaseAppSuite(t, anteOpt)
baseapptestutil.RegisterCounterServer(suite.baseApp.MsgServiceRouter(), CounterServerImpl{t, capKey1, []byte("foo")})
_, err := suite.baseApp.InitChain(&abci.RequestInitChain{
@ -673,6 +677,14 @@ func TestBaseAppPostHandler(t *testing.T) {
require.False(t, res.TxResults[0].IsOK(), fmt.Sprintf("%v", res))
require.True(t, postHandlerRun)
// regression test, should not panic when runMsgs fails
tx = wonkyMsg(t, suite.txConfig, tx)
txBytes, err = suite.txConfig.TxEncoder()(tx)
require.NoError(t, err)
_, err = suite.baseApp.FinalizeBlock(&abci.RequestFinalizeBlock{Height: 1, Txs: [][]byte{txBytes}})
require.NoError(t, err)
require.NotContains(t, suite.logBuffer.String(), "panic recovered in runTx")
}
// Test and ensure that invalid block heights always cause errors.

View File

@ -400,3 +400,17 @@ func setFailOnHandler(t *testing.T, cfg client.TxConfig, tx signing.Tx, fail boo
require.NoError(t, err)
return builder.GetTx()
}
// wonkyMsg is to be used to run a MsgCounter2 message when the MsgCounter2 handler is not registered.
func wonkyMsg(t *testing.T, cfg client.TxConfig, tx signing.Tx) signing.Tx {
t.Helper()
builder := cfg.NewTxBuilder()
builder.SetMemo(tx.GetMemo())
msgs := tx.GetMsgs()
msgs = append(msgs, &baseapptestutil.MsgCounter2{})
err := builder.SetMsgs(msgs...)
require.NoError(t, err)
return builder.GetTx()
}