diff --git a/pkg/core/transaction/invocation.go b/pkg/core/transaction/invocation.go index 1306dbbe8..a73b74bad 100644 --- a/pkg/core/transaction/invocation.go +++ b/pkg/core/transaction/invocation.go @@ -1,6 +1,8 @@ package transaction import ( + "errors" + "github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/util" ) @@ -36,8 +38,16 @@ func NewInvocationTX(script []byte, gas util.Fixed8) *Transaction { // DecodeBinary implements Serializable interface. func (tx *InvocationTX) DecodeBinary(br *io.BinReader) { tx.Script = br.ReadVarBytes() + if br.Err == nil && len(tx.Script) == 0 { + br.Err = errors.New("no script") + return + } if tx.Version >= 1 { tx.Gas.DecodeBinary(br) + if br.Err == nil && tx.Gas.LessThan(0) { + br.Err = errors.New("negative gas") + return + } } else { tx.Gas = util.Fixed8FromInt64(0) } diff --git a/pkg/core/transaction/invocation_test.go b/pkg/core/transaction/invocation_test.go new file mode 100644 index 000000000..a5e46f464 --- /dev/null +++ b/pkg/core/transaction/invocation_test.go @@ -0,0 +1,70 @@ +package transaction + +import ( + "encoding/hex" + "testing" + + "github.com/nspcc-dev/neo-go/pkg/io" + "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestInvocationZeroScript(t *testing.T) { + // Zero-length script. + in, err := hex.DecodeString("000000000000000000") + require.NoError(t, err) + + inv := &InvocationTX{Version: 1} + r := io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.Error(t, r.Err) + + // PUSH1 script. + in, err = hex.DecodeString("01510000000000000000") + require.NoError(t, err) + r = io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.NoError(t, r.Err) +} + +func TestInvocationNegativeGas(t *testing.T) { + // Negative GAS + in, err := hex.DecodeString("015100000000000000ff") + require.NoError(t, err) + + inv := &InvocationTX{Version: 1} + r := io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.Error(t, r.Err) + + // Positive GAS. + in, err = hex.DecodeString("01510100000000000000") + require.NoError(t, err) + r = io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.NoError(t, r.Err) + assert.Equal(t, util.Fixed8(1), inv.Gas) +} + +func TestInvocationVersionZero(t *testing.T) { + in, err := hex.DecodeString("0151") + require.NoError(t, err) + + inv := &InvocationTX{Version: 1} + r := io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.Error(t, r.Err) + + inv = &InvocationTX{Version: 0} + r = io.NewBinReaderFromBuf(in) + + inv.DecodeBinary(r) + assert.NoError(t, r.Err) + assert.Equal(t, util.Fixed8(0), inv.Gas) +}