feat(gov): handle panics when executing x/gov proposals (#17780)
This commit is contained in:
parent
aaf68cdcc0
commit
a0b39a1d31
@ -47,6 +47,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
* (x/bank) [#17569](https://github.com/cosmos/cosmos-sdk/pull/17569) Introduce a new message type, `MsgBurn `, to burn coins.
|
||||
* (genutil) [#17571](https://github.com/cosmos/cosmos-sdk/pull/17571) Allow creation of `AppGenesis` without a file lookup.
|
||||
* (server) [#17094](https://github.com/cosmos/cosmos-sdk/pull/17094) Add duration `shutdown-grace` for resource clean up (closing database handles) before exit.
|
||||
* (x/gov) [#17780](https://github.com/cosmos/cosmos-sdk/pull/17780) Recover panics and turn them into errors when executing x/gov proposals.
|
||||
|
||||
### Improvements
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ import (
|
||||
|
||||
"cosmossdk.io/collections"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/telemetry"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov/keeper"
|
||||
@ -133,9 +134,8 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error {
|
||||
// execute all messages
|
||||
for idx, msg = range messages {
|
||||
handler := keeper.Router().Handler(msg)
|
||||
|
||||
var res *sdk.Result
|
||||
res, err = handler(cacheCtx, msg)
|
||||
res, err = safeExecuteHandler(cacheCtx, msg, handler)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
@ -223,3 +223,15 @@ func EndBlocker(ctx sdk.Context, keeper *keeper.Keeper) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// executes handle(msg) and recovers from panic.
|
||||
func safeExecuteHandler(ctx sdk.Context, msg sdk.Msg, handler baseapp.MsgServiceHandler,
|
||||
) (res *sdk.Result, err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("handling x/gov proposal msg [%s] PANICKED: %v", msg, r)
|
||||
}
|
||||
}()
|
||||
res, err = handler(ctx, msg)
|
||||
return
|
||||
}
|
||||
|
||||
32
x/gov/abci_internal_test.go
Normal file
32
x/gov/abci_internal_test.go
Normal file
@ -0,0 +1,32 @@
|
||||
package gov
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func failingHandler(_ sdk.Context, _ sdk.Msg) (*sdk.Result, error) {
|
||||
panic("test-fail")
|
||||
}
|
||||
|
||||
func okHandler(_ sdk.Context, _ sdk.Msg) (*sdk.Result, error) {
|
||||
return new(sdk.Result), nil
|
||||
}
|
||||
|
||||
func TestSafeExecuteHandler(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require := require.New(t)
|
||||
var ctx sdk.Context
|
||||
|
||||
r, err := safeExecuteHandler(ctx, nil, failingHandler)
|
||||
require.ErrorContains(err, "test-fail")
|
||||
require.Nil(r)
|
||||
|
||||
r, err = safeExecuteHandler(ctx, nil, okHandler)
|
||||
require.Nil(err)
|
||||
require.NotNil(r)
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user