fix types.ChainAnteDecorators() panic (#5742)
* fix types.ChainAnteDecorators() panic ChainAnteDecorators() panics when no arguments are supplied. This change its behaviour and the function now returns a nil AnteHandler in case no AnteDecorator instances are supplied. Closes: #5741 * Append Terminator to non-terminated chains. * Fix test case
This commit is contained in:
+6
-6
@@ -25,15 +25,15 @@ type AnteDecorator interface {
|
||||
// MUST set GasMeter with the FIRST AnteDecorator. Failing to do so will cause
|
||||
// transactions to be processed with an infinite gasmeter and open a DOS attack vector.
|
||||
// Use `ante.SetUpContextDecorator` or a custom Decorator with similar functionality.
|
||||
// Returns nil when no AnteDecorator are supplied.
|
||||
func ChainAnteDecorators(chain ...AnteDecorator) AnteHandler {
|
||||
if (chain[len(chain)-1] != Terminator{}) {
|
||||
chain = append(chain, Terminator{})
|
||||
if len(chain) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(chain) == 1 {
|
||||
return func(ctx Context, tx Tx, simulate bool) (Context, error) {
|
||||
return chain[0].AnteHandle(ctx, tx, simulate, nil)
|
||||
}
|
||||
// handle non-terminated decorators chain
|
||||
if (chain[len(chain)-1] != Terminator{}) {
|
||||
chain = append(chain, Terminator{})
|
||||
}
|
||||
|
||||
return func(ctx Context, tx Tx, simulate bool) (Context, error) {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/tests/mocks"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
||||
func TestChainAnteDecorators(t *testing.T) {
|
||||
t.Parallel()
|
||||
// test panic
|
||||
require.Nil(t, sdk.ChainAnteDecorators([]sdk.AnteDecorator{}...))
|
||||
|
||||
ctx, tx := sdk.Context{}, sdk.Tx(nil)
|
||||
mockCtrl := gomock.NewController(t)
|
||||
mockAnteDecorator1 := mocks.NewMockAnteDecorator(mockCtrl)
|
||||
mockAnteDecorator1.EXPECT().AnteHandle(gomock.Eq(ctx), gomock.Eq(tx), true, gomock.Any()).Times(1)
|
||||
sdk.ChainAnteDecorators(mockAnteDecorator1)(ctx, tx, true)
|
||||
|
||||
mockAnteDecorator2 := mocks.NewMockAnteDecorator(mockCtrl)
|
||||
mockAnteDecorator1.EXPECT().AnteHandle(gomock.Eq(ctx), gomock.Eq(tx), true, mockAnteDecorator2).Times(1)
|
||||
mockAnteDecorator2.EXPECT().AnteHandle(gomock.Eq(ctx), gomock.Eq(tx), true, nil).Times(1)
|
||||
sdk.ChainAnteDecorators(mockAnteDecorator1, mockAnteDecorator2)
|
||||
}
|
||||
Reference in New Issue
Block a user