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:
Alessio Treglia 2020-03-03 16:57:33 +00:00 committed by GitHub
parent 3349c971ae
commit bfac2a9342
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 6 deletions

View File

@ -74,6 +74,7 @@ resulted in a panic when the tx execution mode was `CheckTx`.
* (client) [\#5618](https://github.com/cosmos/cosmos-sdk/pull/5618) Fix crash on the client when the verifier is not set.
* (x/distribution) [\#5620](https://github.com/cosmos/cosmos-sdk/pull/5620) Fix nil pointer deref in distribution tax/rewward validation helpers.
* (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`
* (types) [\#5741](https://github.com/cosmos/cosmos-sdk/issues/5741) Prevent ChainAnteDecorators() from panicking when empty AnteDecorator slice is supplied.
### State Machine Breaking

View File

@ -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) {

28
types/handler_test.go Normal file
View File

@ -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)
}