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:
parent
3349c971ae
commit
bfac2a9342
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue