From a64a0f2681837d8db98830cd7da124fc253362c5 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 28 Apr 2020 16:05:11 +0300 Subject: [PATCH 1/5] vm: reorder arithmetic opcodes --- pkg/rpc/server/server_test.go | 6 +- pkg/rpc/server/testdata/test_contract.avm | Bin 841 -> 851 bytes pkg/rpc/server/testdata/testblocks.acc | Bin 113846 -> 113856 bytes pkg/vm/opcode/opcode.go | 60 +++++------ pkg/vm/opcode/opcode_string.go | 122 +++++++++++----------- pkg/vm/vm.go | 112 ++++++++++---------- 6 files changed, 150 insertions(+), 150 deletions(-) diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index 77b669db6..2d10b8e5e 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -47,18 +47,18 @@ type rpcTestCase struct { check func(t *testing.T, e *executor, result interface{}) } -const testContractHash = "7858559a8405f4e4e1834fcff274ddf4f1b8f407" +const testContractHash = "642e2f47cc6883f0c196cf0dd3dcbb2333300173" var rpcTestCases = map[string][]rpcTestCase{ "getapplicationlog": { { name: "positive", - params: `["fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d"]`, + params: `["953b6e5ba85dd068c2eba5afd2ffdf8ff832b3a791976e2fd896baf5737b2616"]`, result: func(e *executor) interface{} { return &result.ApplicationLog{} }, check: func(t *testing.T, e *executor, acc interface{}) { res, ok := acc.(*result.ApplicationLog) require.True(t, ok) - expectedTxHash, err := util.Uint256DecodeStringLE("fe1a3678b16eca35209acf85397708eb0f1668e4045ad4cd5d2453d3bc0a0a6d") + expectedTxHash, err := util.Uint256DecodeStringLE("953b6e5ba85dd068c2eba5afd2ffdf8ff832b3a791976e2fd896baf5737b2616") require.NoError(t, err) assert.Equal(t, expectedTxHash, res.TxHash) assert.Equal(t, 1, len(res.Executions)) diff --git a/pkg/rpc/server/testdata/test_contract.avm b/pkg/rpc/server/testdata/test_contract.avm index 725dc9a810b3268ed118d60f3c890abb81198f08..a82e371d5c8c53a443ff7d92f1ad29d84a0501cc 100755 GIT binary patch delta 363 zcmX@fcA0I03FGvMrdsu1m>3w!c(_aQOA>Q}OA88eDyORpGcYieGC4T$Gvt(}DPIDs z;7CbL&dg2BDW0y*50VxFNo@y9vE(J@rcPHE0SWW41eGS`faGR_<=BcVbCdFOpl0$g z2ZcI;BYvuGUNP~7jQl)xMW87>{F!-Wi8+}m3W+HxMXANb8D^J* z*c3|zCaW@<3%zFqxtOD*C^4@%Ew!j!J$iB;qYU#rb&birjLM=w$=Bq1A{>vymS&B)DdA_>JWOF8YE|3~=po()- VCMPlJFixJ_&*aY7KKVLR4FDVaUNQgx diff --git a/pkg/rpc/server/testdata/testblocks.acc b/pkg/rpc/server/testdata/testblocks.acc index 1885c851b4d677204000a2f7d78340405f5fff87..d069cd910e4d79a69f2e213930a3727bf8e02fb3 100644 GIT binary patch literal 113856 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≀7 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 G{{IK*8=3k5 literal 113846 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 Date: Wed, 29 Apr 2020 17:13:46 +0300 Subject: [PATCH 2/5] vm: check Integer size on creation --- pkg/vm/stack_item.go | 13 +++++++++---- pkg/vm/vm.go | 23 ----------------------- pkg/vm/vm_test.go | 41 ----------------------------------------- 3 files changed, 9 insertions(+), 68 deletions(-) diff --git a/pkg/vm/stack_item.go b/pkg/vm/stack_item.go index bca4e2745..bba8b8fc3 100644 --- a/pkg/vm/stack_item.go +++ b/pkg/vm/stack_item.go @@ -85,9 +85,7 @@ func makeStackItem(v interface{}) StackItem { value: val, } case *big.Int: - return &BigIntegerItem{ - value: val, - } + return NewBigIntegerItem(val) case StackItem: return val case []int: @@ -311,6 +309,9 @@ type BigIntegerItem struct { // NewBigIntegerItem returns an new BigIntegerItem object. func NewBigIntegerItem(value *big.Int) *BigIntegerItem { + if value.BitLen() > MaxBigIntegerSizeBits { + panic("integer is too big") + } return &BigIntegerItem{ value: value, } @@ -519,7 +520,11 @@ func (i *ByteArrayItem) TryBytes() ([]byte, error) { // TryInteger implements StackItem interface. func (i *ByteArrayItem) TryInteger() (*big.Int, error) { - return emit.BytesToInt(i.value), nil + bi := emit.BytesToInt(i.value) + if bi.BitLen() > MaxBigIntegerSizeBits { + return nil, errors.New("integer is too big") + } + return bi, nil } // Equals implements StackItem interface. diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 6d4051749..721dd3247 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -775,58 +775,43 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro case opcode.INC: x := v.estack.Pop().BigInt() a := new(big.Int).Add(x, big.NewInt(1)) - v.checkBigIntSize(a) v.estack.PushVal(a) case opcode.DEC: x := v.estack.Pop().BigInt() a := new(big.Int).Sub(x, big.NewInt(1)) - v.checkBigIntSize(a) v.estack.PushVal(a) case opcode.ADD: a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) b := v.estack.Pop().BigInt() - v.checkBigIntSize(b) c := new(big.Int).Add(a, b) - v.checkBigIntSize(c) v.estack.PushVal(c) case opcode.SUB: b := v.estack.Pop().BigInt() - v.checkBigIntSize(b) a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) c := new(big.Int).Sub(a, b) - v.checkBigIntSize(c) v.estack.PushVal(c) case opcode.MUL: a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) b := v.estack.Pop().BigInt() - v.checkBigIntSize(b) c := new(big.Int).Mul(a, b) - v.checkBigIntSize(c) v.estack.PushVal(c) case opcode.DIV: b := v.estack.Pop().BigInt() - v.checkBigIntSize(b) a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) v.estack.PushVal(new(big.Int).Quo(a, b)) case opcode.MOD: b := v.estack.Pop().BigInt() - v.checkBigIntSize(b) a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) v.estack.PushVal(new(big.Int).Rem(a, b)) @@ -838,7 +823,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro panic(fmt.Sprintf("operand must be between %d and %d", 0, maxSHLArg)) } a := v.estack.Pop().BigInt() - v.checkBigIntSize(a) var item big.Int if op == opcode.SHL { @@ -847,7 +831,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro item.Rsh(a, uint(b)) } - v.checkBigIntSize(&item) v.estack.PushVal(&item) case opcode.NOT: @@ -1527,12 +1510,6 @@ func (v *VM) checkInvocationStackSize() { } } -func (v *VM) checkBigIntSize(a *big.Int) { - if a.BitLen() > MaxBigIntegerSizeBits { - panic("big integer is too big") - } -} - // bytesToPublicKey is a helper deserializing keys using cache and panicing on // error. func (v *VM) bytesToPublicKey(b []byte) *keys.PublicKey { diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index 2774ad9d8..a5922cdfa 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -1067,31 +1067,6 @@ func TestADDBigResult(t *testing.T) { checkVMFailed(t, vm) } -func testBigArgument(t *testing.T, inst opcode.Opcode) { - prog := makeProgram(inst) - x := getBigInt(MaxBigIntegerSizeBits, 0) - t.Run(inst.String()+" big 1-st argument", func(t *testing.T) { - vm := load(prog) - vm.estack.PushVal(x) - vm.estack.PushVal(0) - checkVMFailed(t, vm) - }) - t.Run(inst.String()+" big 2-nd argument", func(t *testing.T) { - vm := load(prog) - vm.estack.PushVal(0) - vm.estack.PushVal(x) - checkVMFailed(t, vm) - }) -} - -func TestArithBigArgument(t *testing.T) { - testBigArgument(t, opcode.ADD) - testBigArgument(t, opcode.SUB) - testBigArgument(t, opcode.MUL) - testBigArgument(t, opcode.DIV) - testBigArgument(t, opcode.MOD) -} - func TestMul(t *testing.T) { prog := makeProgram(opcode.MUL) vm := load(prog) @@ -1190,14 +1165,6 @@ func TestSHRNegative(t *testing.T) { checkVMFailed(t, vm) } -func TestSHRBigArgument(t *testing.T) { - prog := makeProgram(opcode.SHR) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, 0)) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - func TestSHLGood(t *testing.T) { prog := makeProgram(opcode.SHL) vm := load(prog) @@ -1234,14 +1201,6 @@ func TestSHLBigResult(t *testing.T) { checkVMFailed(t, vm) } -func TestSHLBigArgument(t *testing.T) { - prog := makeProgram(opcode.SHR) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, 0)) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - func TestLT(t *testing.T) { prog := makeProgram(opcode.LT) vm := load(prog) From 9081211f122a182d20cd3d95bcfe2db06ec3d6e8 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 30 Apr 2020 10:52:29 +0300 Subject: [PATCH 3/5] vm: implement NOTEQUAL opcode --- pkg/compiler/codegen.go | 3 +-- pkg/vm/opcode/opcode.go | 11 ++++++----- pkg/vm/vm.go | 4 ++-- pkg/vm/vm_test.go | 18 ++++++++++++++++++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/pkg/compiler/codegen.go b/pkg/compiler/codegen.go index 3ddcb1ecc..d91cdf759 100644 --- a/pkg/compiler/codegen.go +++ b/pkg/compiler/codegen.go @@ -616,8 +616,7 @@ func (c *codegen) Visit(node ast.Node) ast.Visitor { case n.Op == token.NEQ: // VM has separate opcodes for number and string equality if isStringType(c.typeInfo.Types[n.X].Type) { - emit.Opcode(c.prog.BinWriter, opcode.EQUAL) - emit.Opcode(c.prog.BinWriter, opcode.NOT) + emit.Opcode(c.prog.BinWriter, opcode.NOTEQUAL) } else { emit.Opcode(c.prog.BinWriter, opcode.NUMNOTEQUAL) } diff --git a/pkg/vm/opcode/opcode.go b/pkg/vm/opcode/opcode.go index cb453c7b0..071317cdf 100644 --- a/pkg/vm/opcode/opcode.go +++ b/pkg/vm/opcode/opcode.go @@ -98,11 +98,12 @@ const ( RIGHT Opcode = 0x81 // Bitwise logic - INVERT Opcode = 0x90 - AND Opcode = 0x91 - OR Opcode = 0x92 - XOR Opcode = 0x93 - EQUAL Opcode = 0x97 + INVERT Opcode = 0x90 + AND Opcode = 0x91 + OR Opcode = 0x92 + XOR Opcode = 0x93 + EQUAL Opcode = 0x97 + NOTEQUAL Opcode = 0x98 // Arithmetic SIGN Opcode = 0x99 diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 721dd3247..b11bfb876 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -748,7 +748,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro a := v.estack.Pop().BigInt() v.estack.PushVal(new(big.Int).Xor(b, a)) - case opcode.EQUAL: + case opcode.EQUAL, opcode.NOTEQUAL: b := v.estack.Pop() if b == nil { panic("no top-level element found") @@ -757,7 +757,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro if a == nil { panic("no second-to-the-top element found") } - v.estack.PushVal(a.value.Equals(b.value)) + v.estack.PushVal(a.value.Equals(b.value) == (op == opcode.EQUAL)) // Numeric operations. case opcode.SIGN: diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index a5922cdfa..ff50a24d2 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -1319,6 +1319,24 @@ func TestEQUALMapFalse(t *testing.T) { assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) } +func getTestFuncForVM(prog []byte, result interface{}, args ...interface{}) func(t *testing.T) { + return func(t *testing.T) { + v := load(prog) + for i := range args { + v.estack.PushVal(args[i]) + } + runVM(t, v) + require.Equal(t, 1, v.estack.Len()) + require.Equal(t, makeStackItem(result), v.estack.Pop().value) + } +} + +func TestNOTEQUALByteArray(t *testing.T) { + prog := makeProgram(opcode.NOTEQUAL) + t.Run("True", getTestFuncForVM(prog, true, []byte{1, 2}, []byte{0, 1, 2})) + t.Run("False", getTestFuncForVM(prog, false, []byte{1, 2}, []byte{1, 2})) +} + func TestNumEqual(t *testing.T) { prog := makeProgram(opcode.NUMEQUAL) vm := load(prog) From c8328981ec0312abf1eb4de9bb7f602d2658299d Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 30 Apr 2020 11:08:03 +0300 Subject: [PATCH 4/5] vm: refactor tests Most of the tests follow the same logic: push items on stack -> execute program -> check single result. This commit reuses this function in most of the tests. --- pkg/vm/vm_test.go | 1405 ++++++++------------------------------------- 1 file changed, 250 insertions(+), 1155 deletions(-) diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index ff50a24d2..d498386d6 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -174,20 +174,13 @@ func TestStackLimitPUSH1Bad(t *testing.T) { checkVMFailed(t, v) } -func testPUSHINT(t *testing.T, op opcode.Opcode, parameter []byte, expected *big.Int) { - prog := append([]byte{byte(op)}, parameter...) - v := load(prog) - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.EqualValues(t, expected, v.estack.Pop().BigInt()) -} - func TestPUSHINT(t *testing.T) { for i := byte(0); i < 5; i++ { op := opcode.PUSHINT8 + opcode.Opcode(i) t.Run(op.String(), func(t *testing.T) { buf := random.Bytes((8 << i) / 8) - testPUSHINT(t, op, buf, emit.BytesToInt(buf)) + prog := append([]byte{byte(op)}, buf...) + runWithArgs(t, prog, emit.BytesToInt(buf)) }) } } @@ -202,28 +195,14 @@ func TestPUSHNULL(t *testing.T) { } func TestISNULL(t *testing.T) { - t.Run("Integer", func(t *testing.T) { - prog := makeProgram(opcode.PUSH1, opcode.ISNULL) - v := load(prog) - runVM(t, v) - require.False(t, v.estack.Pop().Bool()) - }) - - t.Run("Null", func(t *testing.T) { - prog := makeProgram(opcode.PUSHNULL, opcode.ISNULL) - v := load(prog) - runVM(t, v) - require.True(t, v.estack.Pop().Bool()) - }) + prog := makeProgram(opcode.ISNULL) + t.Run("Integer", getTestFuncForVM(prog, false, 1)) + t.Run("Null", getTestFuncForVM(prog, true, NullItem{})) } func testISTYPE(t *testing.T, result bool, typ StackItemType, item StackItem) { prog := []byte{byte(opcode.ISTYPE), byte(typ)} - v := load(prog) - v.estack.PushVal(item) - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.Equal(t, result, v.estack.Pop().Bool()) + runWithArgs(t, prog, result, item) } func TestISTYPE(t *testing.T) { @@ -257,18 +236,10 @@ func TestISTYPE(t *testing.T) { }) } -func testCONVERT(isErr bool, to StackItemType, item, res StackItem) func(t *testing.T) { +func testCONVERT(to StackItemType, item, res StackItem) func(t *testing.T) { return func(t *testing.T) { prog := []byte{byte(opcode.CONVERT), byte(to)} - v := load(prog) - v.estack.PushVal(item) - if isErr { - checkVMFailed(t, v) - return - } - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.Equal(t, res, v.estack.Pop().value) + runWithArgs(t, prog, res, item) } } @@ -287,7 +258,7 @@ func TestCONVERT(t *testing.T) { t.Run("->Bool", func(t *testing.T) { testBool := func(a, b StackItem) func(t *testing.T) { - return testCONVERT(false, BooleanT, a, b) + return testCONVERT(BooleanT, a, b) } trueCases := []StackItem{ @@ -313,7 +284,7 @@ func TestCONVERT(t *testing.T) { items := []StackItem{NewArrayItem(nil), NewStructItem(nil), NewMapItem(), NewInteropItem(struct{}{})} for _, typ := range types { for j := range items { - t.Run(getName(items[j], typ), testCONVERT(true, typ, items[j], nil)) + t.Run(getName(items[j], typ), testCONVERT(typ, items[j], nil)) } } }) @@ -342,7 +313,7 @@ func TestCONVERT(t *testing.T) { for typ := range trueCases { for _, tc := range trueCases[typ] { - t.Run(getName(tc.item, typ), testCONVERT(false, typ, tc.item, tc.res)) + t.Run(getName(tc.item, typ), testCONVERT(typ, tc.item, tc.res)) } } }) @@ -350,20 +321,20 @@ func TestCONVERT(t *testing.T) { t.Run("Struct<->Array", func(t *testing.T) { arrayItem := NewArrayItem(arr) structItem := NewStructItem(arr) - t.Run("Array->Array", testCONVERT(false, ArrayT, arrayItem, arrayItem)) - t.Run("Array->Struct", testCONVERT(false, StructT, arrayItem, structItem)) - t.Run("Struct->Array", testCONVERT(false, ArrayT, structItem, arrayItem)) - t.Run("Struct->Struct", testCONVERT(false, StructT, structItem, structItem)) + t.Run("Array->Array", testCONVERT(ArrayT, arrayItem, arrayItem)) + t.Run("Array->Struct", testCONVERT(StructT, arrayItem, structItem)) + t.Run("Struct->Array", testCONVERT(ArrayT, structItem, arrayItem)) + t.Run("Struct->Struct", testCONVERT(StructT, structItem, structItem)) }) - t.Run("Map->Map", testCONVERT(false, MapT, m, m)) + t.Run("Map->Map", testCONVERT(MapT, m, m)) t.Run("Null->", func(t *testing.T) { types := []StackItemType{ BooleanT, ByteArrayT, IntegerT, ArrayT, StructT, MapT, InteropT, } for i := range types { - t.Run(types[i].String(), testCONVERT(false, types[i], NullItem{}, NullItem{})) + t.Run(types[i].String(), testCONVERT(types[i], NullItem{}, NullItem{})) } }) @@ -374,7 +345,7 @@ func TestCONVERT(t *testing.T) { } for i := range items { - t.Run(items[i].String(), testCONVERT(true, AnyT, items[i], nil)) + t.Run(items[i].String(), testCONVERT(AnyT, items[i], nil)) } }) } @@ -472,68 +443,24 @@ func TestPushm1to16(t *testing.T) { } } -func TestPushData1BadNoN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA1)} - vm := load(prog) - checkVMFailed(t, vm) +func TestPUSHDATA1(t *testing.T) { + t.Run("Good", getTestFuncForVM([]byte{byte(opcode.PUSHDATA1), 3, 1, 2, 3}, []byte{1, 2, 3})) + t.Run("NoN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA1)}, nil)) + t.Run("BadN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA1), 1}, nil)) } -func TestPushData1BadN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA1), 1} - vm := load(prog) - checkVMFailed(t, vm) +func TestPUSHDATA2(t *testing.T) { + t.Run("Good", getTestFuncForVM([]byte{byte(opcode.PUSHDATA2), 3, 0, 1, 2, 3}, []byte{1, 2, 3})) + t.Run("NoN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA2)}, nil)) + t.Run("ShortN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA2), 0}, nil)) + t.Run("BadN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA2), 1, 0}, nil)) } -func TestPushData1Good(t *testing.T) { - prog := makeProgram(opcode.PUSHDATA1, 3, 1, 2, 3) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) -} - -func TestPushData2BadNoN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA2)} - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestPushData2ShortN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA2), 0} - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestPushData2BadN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA2), 1, 0} - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestPushData2Good(t *testing.T) { - prog := makeProgram(opcode.PUSHDATA2, 3, 0, 1, 2, 3) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) -} - -func TestPushData4BadNoN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA4)} - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestPushData4BadN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA4), 1, 0, 0, 0} - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestPushData4ShortN(t *testing.T) { - prog := []byte{byte(opcode.PUSHDATA4), 0, 0, 0} - vm := load(prog) - checkVMFailed(t, vm) +func TestPUSHDATA4(t *testing.T) { + t.Run("Good", getTestFuncForVM([]byte{byte(opcode.PUSHDATA4), 3, 0, 0, 0, 1, 2, 3}, []byte{1, 2, 3})) + t.Run("NoN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA4)}, nil)) + t.Run("BadN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA4), 1, 0, 0, 0}, nil)) + t.Run("ShortN", getTestFuncForVM([]byte{byte(opcode.PUSHDATA4), 0, 0, 0}, nil)) } func TestPushData4BigN(t *testing.T) { @@ -542,16 +469,7 @@ func TestPushData4BigN(t *testing.T) { binary.LittleEndian.PutUint32(prog[1:], MaxItemSize+1) vm := load(prog) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) -} - -func TestPushData4Good(t *testing.T) { - prog := makeProgram(opcode.PUSHDATA4, 3, 0, 0, 0, 1, 2, 3) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte{1, 2, 3}, vm.estack.Pop().Bytes()) + checkVMFailed(t, vm) } func getEnumeratorProg(n int, isIter bool) (prog []byte) { @@ -822,15 +740,13 @@ func TestSerializeStruct(t *testing.T) { func TestDeserializeUnknown(t *testing.T) { prog := append(getSyscallProg("Neo.Runtime.Deserialize"), byte(opcode.RET)) - vm := load(prog) data, err := SerializeItem(NewBigIntegerItem(big.NewInt(123))) require.NoError(t, err) data[0] = 0xFF - vm.estack.PushVal(data) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, data) } func TestSerializeMap(t *testing.T) { @@ -989,58 +905,15 @@ func TestJMPs(t *testing.T) { } } -func TestNOTNoArgument(t *testing.T) { +func TestNOT(t *testing.T) { prog := makeProgram(opcode.NOT) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestNOTBool(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.PushVal(false) - runVM(t, vm) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) -} - -func TestNOTNonZeroInt(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.PushVal(3) - runVM(t, vm) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) -} - -func TestNOTArray(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - runVM(t, vm) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) -} - -func TestNOTStruct(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.Push(NewElement(&StructItem{[]StackItem{}})) - runVM(t, vm) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) -} - -func TestNOTByteArray0(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.PushVal([]byte{0, 0}) - runVM(t, vm) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) -} - -func TestNOTByteArray1(t *testing.T) { - prog := makeProgram(opcode.NOT) - vm := load(prog) - vm.estack.PushVal([]byte{0, 1}) - runVM(t, vm) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) + t.Run("Bool", getTestFuncForVM(prog, true, false)) + t.Run("NonZeroInt", getTestFuncForVM(prog, false, 3)) + t.Run("Array", getTestFuncForVM(prog, false, []StackItem{})) + t.Run("Struct", getTestFuncForVM(prog, false, NewStructItem([]StackItem{}))) + t.Run("ByteArray0", getTestFuncForVM(prog, true, []byte{0, 0})) + t.Run("ByteArray1", getTestFuncForVM(prog, false, []byte{0, 1})) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) } // getBigInt returns 2^a+b @@ -1050,49 +923,35 @@ func getBigInt(a, b int64) *big.Int { return p } -func TestAdd(t *testing.T) { - prog := makeProgram(opcode.ADD) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, int64(6), vm.estack.Pop().BigInt().Int64()) +func TestArith(t *testing.T) { + // results for 5 and 2 + testCases := map[opcode.Opcode]int{ + opcode.ADD: 7, + opcode.MUL: 10, + opcode.DIV: 2, + opcode.MOD: 1, + opcode.SUB: 3, + } + + for op, res := range testCases { + t.Run(op.String(), getTestFuncForVM(makeProgram(op), res, 5, 2)) + } } func TestADDBigResult(t *testing.T) { prog := makeProgram(opcode.ADD) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, -1)) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestMul(t *testing.T) { - prog := makeProgram(opcode.MUL) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, int64(8), vm.estack.Pop().BigInt().Int64()) + runWithArgs(t, prog, nil, getBigInt(MaxBigIntegerSizeBits, -1), 1) } func TestMULBigResult(t *testing.T) { prog := makeProgram(opcode.MUL) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2+1, 0)) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2+1, 0)) - checkVMFailed(t, vm) + bi := getBigInt(MaxBigIntegerSizeBits/2+1, 0) + runWithArgs(t, prog, nil, bi, bi) } func TestArithNegativeArguments(t *testing.T) { runCase := func(op opcode.Opcode, p, q, result int64) func(t *testing.T) { - return func(t *testing.T) { - vm := load(makeProgram(op)) - vm.estack.PushVal(p) - vm.estack.PushVal(q) - runVM(t, vm) - assert.Equal(t, result, vm.estack.Pop().BigInt().Int64()) - } + return getTestFuncForVM(makeProgram(op), result, p, q) } t.Run("DIV", func(t *testing.T) { @@ -1120,122 +979,44 @@ func TestArithNegativeArguments(t *testing.T) { }) } -func TestSub(t *testing.T) { - prog := makeProgram(opcode.SUB) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, int64(2), vm.estack.Pop().BigInt().Int64()) -} - func TestSUBBigResult(t *testing.T) { prog := makeProgram(opcode.SUB) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits, -1)) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, getBigInt(MaxBigIntegerSizeBits, -1), -1) } -func TestSHRGood(t *testing.T) { +func TestSHR(t *testing.T) { prog := makeProgram(opcode.SHR) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) + t.Run("Good", getTestFuncForVM(prog, 1, 4, 2)) + t.Run("Zero", getTestFuncForVM(prog, []byte{0, 1}, []byte{0, 1}, 0)) + t.Run("Negative", getTestFuncForVM(prog, nil, 5, -1)) } -func TestSHRZero(t *testing.T) { - prog := makeProgram(opcode.SHR) - vm := load(prog) - vm.estack.PushVal([]byte{0, 1}) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) -} - -func TestSHRNegative(t *testing.T) { - prog := makeProgram(opcode.SHR) - vm := load(prog) - vm.estack.PushVal(5) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) -} - -func TestSHLGood(t *testing.T) { +func TestSHL(t *testing.T) { prog := makeProgram(opcode.SHL) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(16), vm.estack.Pop().value) -} - -func TestSHLZero(t *testing.T) { - prog := makeProgram(opcode.SHL) - vm := load(prog) - vm.estack.PushVal([]byte{0, 1}) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) -} - -func TestSHLBigValue(t *testing.T) { - prog := makeProgram(opcode.SHL) - vm := load(prog) - vm.estack.PushVal(5) - vm.estack.PushVal(maxSHLArg + 1) - checkVMFailed(t, vm) -} - -func TestSHLBigResult(t *testing.T) { - prog := makeProgram(opcode.SHL) - vm := load(prog) - vm.estack.PushVal(getBigInt(MaxBigIntegerSizeBits/2, 0)) - vm.estack.PushVal(MaxBigIntegerSizeBits / 2) - checkVMFailed(t, vm) + t.Run("Good", getTestFuncForVM(prog, 16, 4, 2)) + t.Run("Zero", getTestFuncForVM(prog, []byte{0, 1}, []byte{0, 1}, 0)) + t.Run("BigShift", getTestFuncForVM(prog, nil, 5, maxSHLArg+1)) + t.Run("BigResult", getTestFuncForVM(prog, nil, getBigInt(MaxBigIntegerSizeBits/2, 0), MaxBigIntegerSizeBits/2)) } func TestLT(t *testing.T) { prog := makeProgram(opcode.LT) - vm := load(prog) - vm.estack.PushVal(4) - vm.estack.PushVal(3) - runVM(t, vm) - assert.Equal(t, false, vm.estack.Pop().Bool()) + runWithArgs(t, prog, false, 4, 3) } func TestLTE(t *testing.T) { prog := makeProgram(opcode.LTE) - vm := load(prog) - vm.estack.PushVal(2) - vm.estack.PushVal(3) - runVM(t, vm) - assert.Equal(t, true, vm.estack.Pop().Bool()) + runWithArgs(t, prog, true, 2, 3) } func TestGT(t *testing.T) { prog := makeProgram(opcode.GT) - vm := load(prog) - vm.estack.PushVal(9) - vm.estack.PushVal(3) - runVM(t, vm) - assert.Equal(t, true, vm.estack.Pop().Bool()) - + runWithArgs(t, prog, true, 9, 3) } func TestGTE(t *testing.T) { prog := makeProgram(opcode.GTE) - vm := load(prog) - vm.estack.PushVal(3) - vm.estack.PushVal(3) - runVM(t, vm) - assert.Equal(t, true, vm.estack.Pop().Bool()) + runWithArgs(t, prog, true, 3, 3) } func TestDepth(t *testing.T) { @@ -1248,75 +1029,24 @@ func TestDepth(t *testing.T) { assert.Equal(t, int64(3), vm.estack.Pop().BigInt().Int64()) } -func TestEQUALNoArguments(t *testing.T) { - prog := makeProgram(opcode.EQUAL) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestEQUALBad1Argument(t *testing.T) { - prog := makeProgram(opcode.EQUAL) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestEQUALGoodInteger(t *testing.T) { - prog := makeProgram(opcode.EQUAL) - vm := load(prog) - vm.estack.PushVal(5) - vm.estack.PushVal(5) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) -} - -func TestEQUALIntegerByteArray(t *testing.T) { - prog := makeProgram(opcode.EQUAL) - vm := load(prog) - vm.estack.PushVal([]byte{16}) - vm.estack.PushVal(16) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) -} - -func TestEQUALArrayTrue(t *testing.T) { +func TestEQUALTrue(t *testing.T) { prog := makeProgram(opcode.DUP, opcode.EQUAL) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) + t.Run("Array", getTestFuncForVM(prog, true, []StackItem{})) + t.Run("Map", getTestFuncForVM(prog, true, NewMapItem())) } -func TestEQUALArrayFalse(t *testing.T) { +func TestEQUAL(t *testing.T) { prog := makeProgram(opcode.EQUAL) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - vm.estack.PushVal([]StackItem{}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) + t.Run("NoArgs", getTestFuncForVM(prog, nil)) + t.Run("OneArgument", getTestFuncForVM(prog, nil, 1)) + t.Run("Integer", getTestFuncForVM(prog, true, 5, 5)) + t.Run("IntegerByteArray", getTestFuncForVM(prog, true, []byte{16}, 16)) + t.Run("Map", getTestFuncForVM(prog, false, NewMapItem(), NewMapItem())) + t.Run("Array", getTestFuncForVM(prog, false, []StackItem{}, []StackItem{})) } -func TestEQUALMapTrue(t *testing.T) { - prog := makeProgram(opcode.DUP, opcode.EQUAL) - vm := load(prog) - vm.estack.Push(&Element{value: NewMapItem()}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{true}, vm.estack.Pop().value) -} - -func TestEQUALMapFalse(t *testing.T) { - prog := makeProgram(opcode.EQUAL) - vm := load(prog) - vm.estack.Push(&Element{value: NewMapItem()}) - vm.estack.Push(&Element{value: NewMapItem()}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BoolItem{false}, vm.estack.Pop().value) +func runWithArgs(t *testing.T, prog []byte, result interface{}, args ...interface{}) { + getTestFuncForVM(prog, result, args...)(t) } func getTestFuncForVM(prog []byte, result interface{}, args ...interface{}) func(t *testing.T) { @@ -1325,6 +1055,10 @@ func getTestFuncForVM(prog []byte, result interface{}, args ...interface{}) func for i := range args { v.estack.PushVal(args[i]) } + if result == nil { + checkVMFailed(t, v) + return + } runVM(t, v) require.Equal(t, 1, v.estack.Len()) require.Equal(t, makeStackItem(result), v.estack.Pop().value) @@ -1337,30 +1071,21 @@ func TestNOTEQUALByteArray(t *testing.T) { t.Run("False", getTestFuncForVM(prog, false, []byte{1, 2}, []byte{1, 2})) } -func TestNumEqual(t *testing.T) { +func TestNUMEQUAL(t *testing.T) { prog := makeProgram(opcode.NUMEQUAL) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, false, vm.estack.Pop().Bool()) + t.Run("True", getTestFuncForVM(prog, true, 2, 2)) + t.Run("False", getTestFuncForVM(prog, false, 1, 2)) } -func TestNumNotEqual(t *testing.T) { +func TestNUMNOTEQUAL(t *testing.T) { prog := makeProgram(opcode.NUMNOTEQUAL) - vm := load(prog) - vm.estack.PushVal(2) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, false, vm.estack.Pop().Bool()) + t.Run("True", getTestFuncForVM(prog, true, 1, 2)) + t.Run("False", getTestFuncForVM(prog, false, 2, 2)) } func TestINC(t *testing.T) { prog := makeProgram(opcode.INC) - vm := load(prog) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, big.NewInt(2), vm.estack.Pop().BigInt()) + runWithArgs(t, prog, 2, 1) } func TestINCBigResult(t *testing.T) { @@ -1394,37 +1119,23 @@ func TestDECBigResult(t *testing.T) { func TestNEWARRAY0(t *testing.T) { prog := makeProgram(opcode.NEWARRAY0) - v := load(prog) - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.Equal(t, &ArrayItem{[]StackItem{}}, v.estack.Pop().value) + runWithArgs(t, prog, []StackItem{}) } func TestNEWSTRUCT0(t *testing.T) { prog := makeProgram(opcode.NEWSTRUCT0) - v := load(prog) - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.Equal(t, &StructItem{[]StackItem{}}, v.estack.Pop().value) + runWithArgs(t, prog, NewStructItem([]StackItem{})) } -func TestNEWARRAYInteger(t *testing.T) { +func TestNEWARRAYArray(t *testing.T) { prog := makeProgram(opcode.NEWARRAY) - vm := load(prog) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(false)}}, vm.estack.Pop().value) -} + t.Run("ByteArray", getTestFuncForVM(prog, NewArrayItem([]StackItem{}), []byte{})) + t.Run("BadSize", getTestFuncForVM(prog, nil, MaxArraySize+1)) + t.Run("Integer", getTestFuncForVM(prog, []StackItem{NewBoolItem(false)}, 1)) -func TestNEWARRAYStruct(t *testing.T) { - prog := makeProgram(opcode.NEWARRAY) - vm := load(prog) arr := []StackItem{makeStackItem(42)} - vm.estack.Push(&Element{value: &StructItem{arr}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) + t.Run("Array", getTestFuncForVM(prog, arr, arr)) + t.Run("Struct", getTestFuncForVM(prog, arr, NewStructItem(arr))) } func testNEWARRAYIssue437(t *testing.T, i1, i2 opcode.Opcode, appended bool) { @@ -1460,38 +1171,6 @@ func TestNEWARRAYIssue437(t *testing.T) { t.Run("Struct+Array", func(t *testing.T) { testNEWARRAYIssue437(t, opcode.NEWSTRUCT, opcode.NEWARRAY, false) }) } -func TestNEWARRAYArray(t *testing.T) { - prog := makeProgram(opcode.NEWARRAY) - vm := load(prog) - arr := []StackItem{makeStackItem(42)} - vm.estack.Push(&Element{value: &ArrayItem{arr}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{arr}, vm.estack.Pop().value) -} - -func TestNEWARRAYByteArray(t *testing.T) { - prog := makeProgram(opcode.NEWARRAY) - vm := load(prog) - vm.estack.PushVal([]byte{}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{[]StackItem{}}, vm.estack.Pop().value) -} - -func testNEWARRAYT(t *testing.T, typ StackItemType, item StackItem) { - prog := makeProgram(opcode.NEWARRAYT, opcode.Opcode(typ), opcode.PUSH0, opcode.PICKITEM) - v := load(prog) - v.estack.PushVal(1) - if item == nil { - checkVMFailed(t, v) - return - } - runVM(t, v) - require.Equal(t, 1, v.estack.Len()) - require.Equal(t, item, v.estack.Pop().Item()) -} - func TestNEWARRAYT(t *testing.T) { testCases := map[StackItemType]StackItem{ BooleanT: NewBoolItem(false), @@ -1501,111 +1180,41 @@ func TestNEWARRAYT(t *testing.T) { 0xFF: nil, } for typ, item := range testCases { - t.Run(typ.String(), func(t *testing.T) { testNEWARRAYT(t, typ, item) }) + prog := makeProgram(opcode.NEWARRAYT, opcode.Opcode(typ), opcode.PUSH0, opcode.PICKITEM) + t.Run(typ.String(), getTestFuncForVM(prog, item, 1)) } } -func TestNEWARRAYBadSize(t *testing.T) { - prog := makeProgram(opcode.NEWARRAY) - vm := load(prog) - vm.estack.PushVal(MaxArraySize + 1) - checkVMFailed(t, vm) -} - -func TestNEWSTRUCTInteger(t *testing.T) { +func TestNEWSTRUCT(t *testing.T) { prog := makeProgram(opcode.NEWSTRUCT) - vm := load(prog) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &StructItem{[]StackItem{makeStackItem(false)}}, vm.estack.Pop().value) -} + t.Run("ByteArray", getTestFuncForVM(prog, NewStructItem([]StackItem{}), []byte{})) + t.Run("BadSize", getTestFuncForVM(prog, nil, MaxArraySize+1)) + t.Run("Integer", getTestFuncForVM(prog, NewStructItem([]StackItem{NewBoolItem(false)}), 1)) -func TestNEWSTRUCTArray(t *testing.T) { - prog := makeProgram(opcode.NEWSTRUCT) - vm := load(prog) arr := []StackItem{makeStackItem(42)} - vm.estack.Push(&Element{value: &ArrayItem{arr}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) + t.Run("Array", getTestFuncForVM(prog, NewStructItem(arr), NewArrayItem(arr))) + t.Run("Struct", getTestFuncForVM(prog, NewStructItem(arr), NewStructItem(arr))) } -func TestNEWSTRUCTStruct(t *testing.T) { - prog := makeProgram(opcode.NEWSTRUCT) - vm := load(prog) - arr := []StackItem{makeStackItem(42)} - vm.estack.Push(&Element{value: &StructItem{arr}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &StructItem{arr}, vm.estack.Pop().value) -} - -func TestNEWSTRUCTByteArray(t *testing.T) { - prog := makeProgram(opcode.NEWSTRUCT) - vm := load(prog) - vm.estack.PushVal([]byte{}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &StructItem{[]StackItem{}}, vm.estack.Pop().value) -} - -func TestNEWSTRUCTBadSize(t *testing.T) { - prog := makeProgram(opcode.NEWSTRUCT) - vm := load(prog) - vm.estack.PushVal(MaxArraySize + 1) - checkVMFailed(t, vm) -} - -func TestAPPENDArray(t *testing.T) { +func TestAPPEND(t *testing.T) { prog := makeProgram(opcode.DUP, opcode.PUSH5, opcode.APPEND) - vm := load(prog) - vm.estack.Push(&Element{value: &ArrayItem{}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(5)}}, vm.estack.Pop().value) -} - -func TestAPPENDStruct(t *testing.T) { - prog := makeProgram(opcode.DUP, opcode.PUSH5, opcode.APPEND) - vm := load(prog) - vm.estack.Push(&Element{value: &StructItem{}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &StructItem{[]StackItem{makeStackItem(5)}}, vm.estack.Pop().value) + arr := []StackItem{makeStackItem(5)} + t.Run("Array", getTestFuncForVM(prog, NewArrayItem(arr), NewArrayItem(nil))) + t.Run("Struct", getTestFuncForVM(prog, NewStructItem(arr), NewStructItem(nil))) } func TestAPPENDCloneStruct(t *testing.T) { prog := makeProgram(opcode.DUP, opcode.PUSH0, opcode.NEWSTRUCT, opcode.TOALTSTACK, opcode.DUPFROMALTSTACK, opcode.APPEND, opcode.FROMALTSTACK, opcode.PUSH1, opcode.APPEND) - vm := load(prog) - vm.estack.Push(&Element{value: &ArrayItem{}}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{[]StackItem{ - &StructItem{[]StackItem{}}, - }}, vm.estack.Pop().value) + arr := []StackItem{&StructItem{[]StackItem{}}} + runWithArgs(t, prog, NewArrayItem(arr), NewArrayItem(nil)) } -func TestAPPENDBadNoArguments(t *testing.T) { +func TestAPPENDBad(t *testing.T) { prog := makeProgram(opcode.APPEND) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestAPPENDBad1Argument(t *testing.T) { - prog := makeProgram(opcode.APPEND) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestAPPENDWrongType(t *testing.T) { - prog := makeProgram(opcode.APPEND) - vm := load(prog) - vm.estack.PushVal([]byte{}) - vm.estack.PushVal(1) - checkVMFailed(t, vm) + t.Run("no arguments", getTestFuncForVM(prog, nil)) + t.Run("one argument", getTestFuncForVM(prog, nil, 1)) + t.Run("wrong type", getTestFuncForVM(prog, nil, []byte{}, 1)) } func TestAPPENDGoodSizeLimit(t *testing.T) { @@ -1619,37 +1228,14 @@ func TestAPPENDGoodSizeLimit(t *testing.T) { func TestAPPENDBadSizeLimit(t *testing.T) { prog := makeProgram(opcode.NEWARRAY, opcode.DUP, opcode.PUSH0, opcode.APPEND) - vm := load(prog) - vm.estack.PushVal(MaxArraySize) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, MaxArraySize) } -func TestPICKITEMBadIndex(t *testing.T) { +func TestPICKITEM(t *testing.T) { prog := makeProgram(opcode.PICKITEM) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - vm.estack.PushVal(0) - checkVMFailed(t, vm) -} - -func TestPICKITEMArray(t *testing.T) { - prog := makeProgram(opcode.PICKITEM) - vm := load(prog) - vm.estack.PushVal([]StackItem{makeStackItem(1), makeStackItem(2)}) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) -} - -func TestPICKITEMByteArray(t *testing.T) { - prog := makeProgram(opcode.PICKITEM) - vm := load(prog) - vm.estack.PushVal([]byte{1, 2}) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) + t.Run("bad index", getTestFuncForVM(prog, nil, []StackItem{}, 0)) + t.Run("Array", getTestFuncForVM(prog, 2, []StackItem{makeStackItem(1), makeStackItem(2)}, 1)) + t.Run("ByteArray", getTestFuncForVM(prog, 2, []byte{1, 2}, 1)) } func TestPICKITEMDupArray(t *testing.T) { @@ -1680,48 +1266,26 @@ func TestPICKITEMDupMap(t *testing.T) { func TestPICKITEMMap(t *testing.T) { prog := makeProgram(opcode.PICKITEM) - vm := load(prog) - m := NewMapItem() m.Add(makeStackItem(5), makeStackItem(3)) - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(makeStackItem(5)) - - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(3), vm.estack.Pop().value) + runWithArgs(t, prog, 3, m, 5) } func TestSETITEMMap(t *testing.T) { prog := makeProgram(opcode.SETITEM, opcode.PICKITEM) - vm := load(prog) - m := NewMapItem() m.Add(makeStackItem(5), makeStackItem(3)) - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(5) - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(5) - vm.estack.PushVal([]byte{0, 1}) - - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem([]byte{0, 1}), vm.estack.Pop().value) + runWithArgs(t, prog, []byte{0, 1}, m, 5, m, 5, []byte{0, 1}) } func TestSETITEMBigMapBad(t *testing.T) { prog := makeProgram(opcode.SETITEM) - vm := load(prog) - m := NewMapItem() for i := 0; i < MaxArraySize; i++ { m.Add(makeStackItem(i), makeStackItem(i)) } - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(MaxArraySize) - vm.estack.PushVal(0) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, m, MaxArraySize, 0) } func TestSETITEMBigMapGood(t *testing.T) { @@ -1739,54 +1303,18 @@ func TestSETITEMBigMapGood(t *testing.T) { runVM(t, vm) } -func TestSIZENoArgument(t *testing.T) { +func TestSIZE(t *testing.T) { prog := makeProgram(opcode.SIZE) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestSIZEByteArray(t *testing.T) { - prog := makeProgram(opcode.SIZE) - vm := load(prog) - vm.estack.PushVal([]byte{0, 1}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) -} - -func TestSIZEBool(t *testing.T) { - prog := makeProgram(opcode.SIZE) - vm := load(prog) - vm.estack.PushVal(false) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) -} - -func TestSIZEArray(t *testing.T) { - prog := makeProgram(opcode.SIZE) - vm := load(prog) - vm.estack.PushVal([]StackItem{ - makeStackItem(1), - makeStackItem([]byte{}), + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("ByteArray", getTestFuncForVM(prog, 2, []byte{0, 1})) + t.Run("Bool", getTestFuncForVM(prog, 1, false)) + t.Run("Array", getTestFuncForVM(prog, 2, []StackItem{makeStackItem(1), makeStackItem([]byte{})})) + t.Run("Map", func(t *testing.T) { + m := NewMapItem() + m.Add(makeStackItem(5), makeStackItem(6)) + m.Add(makeStackItem([]byte{0, 1}), makeStackItem(6)) + runWithArgs(t, prog, 2, m) }) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) -} - -func TestSIZEMap(t *testing.T) { - prog := makeProgram(opcode.SIZE) - vm := load(prog) - - m := NewMapItem() - m.Add(makeStackItem(5), makeStackItem(6)) - m.Add(makeStackItem([]byte{0, 1}), makeStackItem(6)) - vm.estack.Push(&Element{value: m}) - - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) } func TestKEYSMap(t *testing.T) { @@ -1807,17 +1335,10 @@ func TestKEYSMap(t *testing.T) { assert.Contains(t, top.value, makeStackItem([]byte{0, 1})) } -func TestKEYSNoArgument(t *testing.T) { +func TestKEYS(t *testing.T) { prog := makeProgram(opcode.KEYS) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestKEYSWrongType(t *testing.T) { - prog := makeProgram(opcode.KEYS) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("WrongType", getTestFuncForVM(prog, nil, []StackItem{})) } func TestVALUESMap(t *testing.T) { @@ -1838,169 +1359,48 @@ func TestVALUESMap(t *testing.T) { assert.Contains(t, top.value, makeStackItem([]StackItem{})) } -func TestVALUESArray(t *testing.T) { +func TestVALUES(t *testing.T) { prog := makeProgram(opcode.VALUES) - vm := load(prog) - vm.estack.PushVal([]StackItem{makeStackItem(4)}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ArrayItem{[]StackItem{makeStackItem(4)}}, vm.estack.Pop().value) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("WrongType", getTestFuncForVM(prog, nil, 5)) + t.Run("Array", getTestFuncForVM(prog, []int{4}, []int{4})) } -func TestVALUESNoArgument(t *testing.T) { - prog := makeProgram(opcode.VALUES) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestVALUESWrongType(t *testing.T) { - prog := makeProgram(opcode.VALUES) - vm := load(prog) - vm.estack.PushVal(5) - checkVMFailed(t, vm) -} - -func TestHASKEYArrayTrue(t *testing.T) { - prog := makeProgram(opcode.PUSH5, opcode.NEWARRAY, opcode.PUSH4, opcode.HASKEY) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) -} - -func TestHASKEYArrayFalse(t *testing.T) { - prog := makeProgram(opcode.PUSH5, opcode.NEWARRAY, opcode.PUSH5, opcode.HASKEY) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) -} - -func TestHASKEYStructTrue(t *testing.T) { - prog := makeProgram(opcode.PUSH5, opcode.NEWSTRUCT, opcode.PUSH4, opcode.HASKEY) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) -} - -func TestHASKEYStructFalse(t *testing.T) { - prog := makeProgram(opcode.PUSH5, opcode.NEWSTRUCT, opcode.PUSH5, opcode.HASKEY) - vm := load(prog) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) -} - -func TestHASKEYMapTrue(t *testing.T) { +func TestHASKEY(t *testing.T) { + prog := makeProgram(opcode.HASKEY) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("OneArgument", getTestFuncForVM(prog, nil, 1)) + t.Run("WrongKeyType", getTestFuncForVM(prog, nil, []StackItem{}, []StackItem{})) + t.Run("WrongCollectionType", getTestFuncForVM(prog, nil, 1, 2)) + + arr := makeArrayOfType(5, BooleanT) + t.Run("Array", func(t *testing.T) { + t.Run("True", getTestFuncForVM(prog, true, NewArrayItem(arr), 4)) + t.Run("False", getTestFuncForVM(prog, false, NewArrayItem(arr), 5)) + }) + t.Run("Struct", func(t *testing.T) { + t.Run("True", getTestFuncForVM(prog, true, NewStructItem(arr), 4)) + t.Run("False", getTestFuncForVM(prog, false, NewStructItem(arr), 5)) + }) +} + +func TestHASKEYMap(t *testing.T) { prog := makeProgram(opcode.HASKEY) - vm := load(prog) m := NewMapItem() m.Add(makeStackItem(5), makeStackItem(6)) - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(5) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(true), vm.estack.Pop().value) + t.Run("True", getTestFuncForVM(prog, true, m, 5)) + t.Run("False", getTestFuncForVM(prog, false, m, 6)) } -func TestHASKEYMapFalse(t *testing.T) { - prog := makeProgram(opcode.HASKEY) - vm := load(prog) - m := NewMapItem() - m.Add(makeStackItem(5), makeStackItem(6)) - vm.estack.Push(&Element{value: m}) - vm.estack.PushVal(6) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) -} - -func TestHASKEYNoArguments(t *testing.T) { - prog := makeProgram(opcode.HASKEY) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestHASKEY1Argument(t *testing.T) { - prog := makeProgram(opcode.HASKEY) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestHASKEYWrongKeyType(t *testing.T) { - prog := makeProgram(opcode.HASKEY) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - vm.estack.PushVal([]StackItem{}) - checkVMFailed(t, vm) -} - -func TestHASKEYWrongCollectionType(t *testing.T) { - prog := makeProgram(opcode.HASKEY) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestSIGNNoArgument(t *testing.T) { +func TestSIGN(t *testing.T) { prog := makeProgram(opcode.SIGN) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestSIGNWrongType(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal([]StackItem{}) - checkVMFailed(t, vm) -} - -func TestSIGNBool(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal(false) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BigIntegerItem{big.NewInt(0)}, vm.estack.Pop().value) -} - -func TestSIGNPositiveInt(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BigIntegerItem{big.NewInt(1)}, vm.estack.Pop().value) -} - -func TestSIGNNegativeInt(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal(-1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BigIntegerItem{big.NewInt(-1)}, vm.estack.Pop().value) -} - -func TestSIGNZero(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BigIntegerItem{big.NewInt(0)}, vm.estack.Pop().value) -} - -func TestSIGNByteArray(t *testing.T) { - prog := makeProgram(opcode.SIGN) - vm := load(prog) - vm.estack.PushVal([]byte{0, 1}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &BigIntegerItem{big.NewInt(1)}, vm.estack.Pop().value) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("WrongType", getTestFuncForVM(prog, nil, []StackItem{})) + t.Run("Bool", getTestFuncForVM(prog, 0, false)) + t.Run("PositiveInt", getTestFuncForVM(prog, 1, 2)) + t.Run("NegativeInt", getTestFuncForVM(prog, -1, -1)) + t.Run("Zero", getTestFuncForVM(prog, 0, 0)) + t.Run("ByteArray", getTestFuncForVM(prog, 1, []byte{0, 1})) } func TestAppCall(t *testing.T) { @@ -2082,34 +1482,16 @@ func TestSimpleCall(t *testing.T) { assert.Equal(t, result, int(vm.estack.Pop().BigInt().Int64())) } -func TestNZtrue(t *testing.T) { +func TestNZ(t *testing.T) { prog := makeProgram(opcode.NZ) - vm := load(prog) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, true, vm.estack.Pop().Bool()) + t.Run("True", getTestFuncForVM(prog, true, 1)) + t.Run("False", getTestFuncForVM(prog, false, 0)) } -func TestNZfalse(t *testing.T) { - prog := makeProgram(opcode.NZ) - vm := load(prog) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, false, vm.estack.Pop().Bool()) -} - -func TestPICKbadNoitem(t *testing.T) { +func TestPICK(t *testing.T) { prog := makeProgram(opcode.PICK) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestPICKbadNegative(t *testing.T) { - prog := makeProgram(opcode.PICK) - vm := load(prog) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) + t.Run("NoItem", getTestFuncForVM(prog, nil, 1)) + t.Run("Negative", getTestFuncForVM(prog, nil, -1)) } func TestPICKgood(t *testing.T) { @@ -2144,10 +1526,7 @@ func TestPICKDup(t *testing.T) { func TestROTBad(t *testing.T) { prog := makeProgram(opcode.ROT) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1, 2) } func TestROTGood(t *testing.T) { @@ -2165,20 +1544,12 @@ func TestROTGood(t *testing.T) { func TestROLLBad1(t *testing.T) { prog := makeProgram(opcode.ROLL) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1, -1) } func TestROLLBad2(t *testing.T) { prog := makeProgram(opcode.ROLL) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - vm.estack.PushVal(3) - vm.estack.PushVal(3) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1, 2, 3, 3) } func TestROLLGood(t *testing.T) { @@ -2197,34 +1568,12 @@ func TestROLLGood(t *testing.T) { assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) } -func TestXTUCKbadNoitem(t *testing.T) { +func TestXTUCK(t *testing.T) { prog := makeProgram(opcode.XTUCK) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestXTUCKbadNoN(t *testing.T) { - prog := makeProgram(opcode.XTUCK) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestXTUCKbadNegative(t *testing.T) { - prog := makeProgram(opcode.XTUCK) - vm := load(prog) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) -} - -func TestXTUCKbadZero(t *testing.T) { - prog := makeProgram(opcode.XTUCK) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(0) - checkVMFailed(t, vm) + t.Run("NoItem", getTestFuncForVM(prog, nil, 1)) + t.Run("NoN", getTestFuncForVM(prog, nil, 1, 2)) + t.Run("Negative", getTestFuncForVM(prog, nil, -1)) + t.Run("Zero", getTestFuncForVM(prog, nil, 1, 0)) } func TestXTUCKgood(t *testing.T) { @@ -2246,15 +1595,8 @@ func TestXTUCKgood(t *testing.T) { func TestTUCKbadNoitems(t *testing.T) { prog := makeProgram(opcode.TUCK) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestTUCKbadNoitem(t *testing.T) { - prog := makeProgram(opcode.TUCK) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("NoItem", getTestFuncForVM(prog, nil, 1)) } func TestTUCKgood(t *testing.T) { @@ -2281,19 +1623,10 @@ func TestTUCKgood2(t *testing.T) { assert.Equal(t, int64(11), vm.estack.Peek(3).BigInt().Int64()) } -func TestOVERbadNoitem(t *testing.T) { +func TestOVER(t *testing.T) { prog := makeProgram(opcode.OVER) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) -} - -func TestOVERbadNoitems(t *testing.T) { - prog := makeProgram(opcode.OVER) - vm := load(prog) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("NoItem", getTestFuncForVM(prog, nil, 1)) } func TestOVERgood(t *testing.T) { @@ -2326,25 +1659,17 @@ func TestOVERDup(t *testing.T) { func TestNIPBadNoItem(t *testing.T) { prog := makeProgram(opcode.NIP) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1) } func TestNIPGood(t *testing.T) { prog := makeProgram(opcode.NIP) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) + runWithArgs(t, prog, 2, 1, 2) } func TestDROPBadNoItem(t *testing.T) { prog := makeProgram(opcode.DROP) - vm := load(prog) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil) } func TestDROPGood(t *testing.T) { @@ -2355,26 +1680,11 @@ func TestDROPGood(t *testing.T) { assert.Equal(t, 0, vm.estack.Len()) } -func TestXDROPbadNoitem(t *testing.T) { +func TestXDROP(t *testing.T) { prog := makeProgram(opcode.XDROP) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestXDROPbadNoN(t *testing.T) { - prog := makeProgram(opcode.XDROP) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestXDROPbadNegative(t *testing.T) { - prog := makeProgram(opcode.XDROP) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("NoN", getTestFuncForVM(prog, nil, 1, 2)) + t.Run("Negative", getTestFuncForVM(prog, nil, 1, -1)) } func TestXDROPgood(t *testing.T) { @@ -2392,16 +1702,12 @@ func TestXDROPgood(t *testing.T) { func TestINVERTbadNoitem(t *testing.T) { prog := makeProgram(opcode.INVERT) - vm := load(prog) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil) } func TestINVERTgood1(t *testing.T) { prog := makeProgram(opcode.INVERT) - vm := load(prog) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, int64(-1), vm.estack.Peek(0).BigInt().Int64()) + runWithArgs(t, prog, -1, 0) } func TestINVERTgood2(t *testing.T) { @@ -2434,107 +1740,29 @@ func TestINVERTWithConversion2(t *testing.T) { assert.Equal(t, int64(-1), vm.estack.Peek(0).BigInt().Int64()) } -func TestCATBadNoArgs(t *testing.T) { +func TestCAT(t *testing.T) { prog := makeProgram(opcode.CAT) - vm := load(prog) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("OneArgument", getTestFuncForVM(prog, nil, []byte("abc"))) + t.Run("BigItem", func(t *testing.T) { + arg := make([]byte, MaxItemSize/2+1) + runWithArgs(t, prog, nil, arg, arg) + }) + t.Run("Good", getTestFuncForVM(prog, []byte("abcdef"), []byte("abc"), []byte("def"))) + t.Run("Int0ByteArray", getTestFuncForVM(prog, []byte{}, 0, []byte{})) + t.Run("ByteArrayInt1", getTestFuncForVM(prog, []byte{1}, []byte{}, 1)) } -func TestCATBadOneArg(t *testing.T) { - prog := makeProgram(opcode.CAT) - vm := load(prog) - vm.estack.PushVal([]byte("abc")) - checkVMFailed(t, vm) -} - -func TestCATBadBigItem(t *testing.T) { - prog := makeProgram(opcode.CAT) - vm := load(prog) - vm.estack.PushVal(make([]byte, MaxItemSize/2+1)) - vm.estack.PushVal(make([]byte, MaxItemSize/2+1)) - vm.Run() - assert.Equal(t, true, vm.HasFailed()) -} - -func TestCATGood(t *testing.T) { - prog := makeProgram(opcode.CAT) - vm := load(prog) - vm.estack.PushVal([]byte("abc")) - vm.estack.PushVal([]byte("def")) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte("abcdef"), vm.estack.Peek(0).Bytes()) -} - -func TestCATInt0ByteArray(t *testing.T) { - prog := makeProgram(opcode.CAT) - vm := load(prog) - vm.estack.PushVal(0) - vm.estack.PushVal([]byte{}) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ByteArrayItem{[]byte{}}, vm.estack.Pop().value) -} - -func TestCATByteArrayInt1(t *testing.T) { - prog := makeProgram(opcode.CAT) - vm := load(prog) - vm.estack.PushVal([]byte{}) - vm.estack.PushVal(1) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, &ByteArrayItem{[]byte{1}}, vm.estack.Pop().value) -} - -func TestSUBSTRBadNoArgs(t *testing.T) { +func TestSUBSTR(t *testing.T) { prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestSUBSTRBadOneArg(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestSUBSTRBadTwoArgs(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal(0) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestSUBSTRGood(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte("bc"), vm.estack.Peek(0).Bytes()) -} - -func TestSUBSTRBadOffset(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(7) - vm.estack.PushVal(1) - - checkVMFailed(t, vm) -} - -func TestSUBSTRBigLen(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(1) - vm.estack.PushVal(6) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("OneArgument", getTestFuncForVM(prog, nil, 1)) + t.Run("TwoArguments", getTestFuncForVM(prog, nil, 0, 2)) + t.Run("Good", getTestFuncForVM(prog, []byte("bc"), []byte("abcdef"), 1, 2)) + t.Run("BadOffset", getTestFuncForVM(prog, nil, []byte("abcdef"), 7, 1)) + t.Run("BigLen", getTestFuncForVM(prog, nil, []byte("abcdef"), 1, 6)) + t.Run("NegativeOffset", getTestFuncForVM(prog, nil, []byte("abcdef"), -1, 3)) + t.Run("NegativeLen", getTestFuncForVM(prog, nil, []byte("abcdef"), 3, -1)) } func TestSUBSTRBad387(t *testing.T) { @@ -2548,109 +1776,28 @@ func TestSUBSTRBad387(t *testing.T) { checkVMFailed(t, vm) } -func TestSUBSTRBadNegativeOffset(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(-1) - vm.estack.PushVal(3) - checkVMFailed(t, vm) -} - -func TestSUBSTRBadNegativeLen(t *testing.T) { - prog := makeProgram(opcode.SUBSTR) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(3) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) -} - -func TestLEFTBadNoArgs(t *testing.T) { +func TestLEFT(t *testing.T) { prog := makeProgram(opcode.LEFT) - vm := load(prog) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("NoString", getTestFuncForVM(prog, nil, 2)) + t.Run("NegativeLen", getTestFuncForVM(prog, nil, "abcdef", -1)) + t.Run("Good", getTestFuncForVM(prog, "ab", "abcdef", 2)) + t.Run("GoodBigLen", getTestFuncForVM(prog, "abcdef", "abcdef", 8)) } -func TestLEFTBadNoString(t *testing.T) { - prog := makeProgram(opcode.LEFT) - vm := load(prog) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestLEFTBadNegativeLen(t *testing.T) { - prog := makeProgram(opcode.LEFT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) -} - -func TestLEFTGood(t *testing.T) { - prog := makeProgram(opcode.LEFT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte("ab"), vm.estack.Peek(0).Bytes()) -} - -func TestLEFTGoodLen(t *testing.T) { - prog := makeProgram(opcode.LEFT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(8) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte("abcdef"), vm.estack.Peek(0).Bytes()) -} - -func TestRIGHTBadNoArgs(t *testing.T) { +func TestRIGHT(t *testing.T) { prog := makeProgram(opcode.RIGHT) - vm := load(prog) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("NoString", getTestFuncForVM(prog, nil, 2)) + t.Run("NegativeLen", getTestFuncForVM(prog, nil, "abcdef", -1)) + t.Run("Good", getTestFuncForVM(prog, "ef", "abcdef", 2)) + t.Run("BadLen", getTestFuncForVM(prog, nil, "abcdef", 8)) } -func TestRIGHTBadNoString(t *testing.T) { - prog := makeProgram(opcode.RIGHT) - vm := load(prog) - vm.estack.PushVal(2) - checkVMFailed(t, vm) -} - -func TestRIGHTBadNegativeLen(t *testing.T) { - prog := makeProgram(opcode.RIGHT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) -} - -func TestRIGHTGood(t *testing.T) { - prog := makeProgram(opcode.RIGHT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(2) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []byte("ef"), vm.estack.Peek(0).Bytes()) -} - -func TestRIGHTBadLen(t *testing.T) { - prog := makeProgram(opcode.RIGHT) - vm := load(prog) - vm.estack.PushVal([]byte("abcdef")) - vm.estack.PushVal(8) - checkVMFailed(t, vm) -} - -func TestPACKBadLen(t *testing.T) { +func TestPACK(t *testing.T) { prog := makeProgram(opcode.PACK) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) + t.Run("BadLen", getTestFuncForVM(prog, nil, 1)) + t.Run("Good0Len", getTestFuncForVM(prog, []StackItem{}, 0)) } func TestPACKBigLen(t *testing.T) { @@ -2663,15 +1810,6 @@ func TestPACKBigLen(t *testing.T) { checkVMFailed(t, vm) } -func TestPACKGoodZeroLen(t *testing.T) { - prog := makeProgram(opcode.PACK) - vm := load(prog) - vm.estack.PushVal(0) - runVM(t, vm) - assert.Equal(t, 1, vm.estack.Len()) - assert.Equal(t, []StackItem{}, vm.estack.Peek(0).Array()) -} - func TestPACKGood(t *testing.T) { prog := makeProgram(opcode.PACK) elements := []int{55, 34, 42} @@ -2695,9 +1833,7 @@ func TestPACKGood(t *testing.T) { func TestUNPACKBadNotArray(t *testing.T) { prog := makeProgram(opcode.UNPACK) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1) } func TestUNPACKGood(t *testing.T) { @@ -2820,34 +1956,12 @@ func TestREVERSEITEMSGood(t *testing.T) { } } -func TestREMOVEBadNoArgs(t *testing.T) { +func TestREMOVE(t *testing.T) { prog := makeProgram(opcode.REMOVE) - vm := load(prog) - checkVMFailed(t, vm) -} - -func TestREMOVEBadOneArg(t *testing.T) { - prog := makeProgram(opcode.REMOVE) - vm := load(prog) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestREMOVEBadNotArray(t *testing.T) { - prog := makeProgram(opcode.REMOVE) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(1) - checkVMFailed(t, vm) -} - -func TestREMOVEBadIndex(t *testing.T) { - prog := makeProgram(opcode.REMOVE) - elements := []int{22, 34, 42, 55, 81} - vm := load(prog) - vm.estack.PushVal(elements) - vm.estack.PushVal(10) - checkVMFailed(t, vm) + t.Run("NoArgument", getTestFuncForVM(prog, nil)) + t.Run("OneArgument", getTestFuncForVM(prog, nil, 1)) + t.Run("NotArray", getTestFuncForVM(prog, nil, 1, 1)) + t.Run("BadIndex", getTestFuncForVM(prog, nil, []int{22, 34, 42, 55, 81}, 10)) } func TestREMOVEGood(t *testing.T) { @@ -2910,9 +2024,7 @@ func TestCLEARITEMS(t *testing.T) { t.Run("Integer", func(t *testing.T) { prog := makeProgram(opcode.CLEARITEMS) - v := load(prog) - v.estack.PushVal(1) - checkVMFailed(t, v) + runWithArgs(t, prog, nil, 1) }) } @@ -2927,17 +2039,10 @@ func TestSWAPGood(t *testing.T) { assert.Equal(t, int64(4), vm.estack.Pop().BigInt().Int64()) } -func TestSWAPBad1(t *testing.T) { +func TestSWAP(t *testing.T) { prog := makeProgram(opcode.SWAP) - vm := load(prog) - vm.estack.PushVal(4) - checkVMFailed(t, vm) -} - -func TestSWAPBad2(t *testing.T) { - prog := makeProgram(opcode.SWAP) - vm := load(prog) - checkVMFailed(t, vm) + t.Run("EmptyStack", getTestFuncForVM(prog, nil)) + t.Run("SmallStack", getTestFuncForVM(prog, nil, 4)) } func TestXSWAPGood(t *testing.T) { @@ -2960,22 +2065,12 @@ func TestXSWAPGood(t *testing.T) { func TestXSWAPBad1(t *testing.T) { prog := makeProgram(opcode.XSWAP) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - vm.estack.PushVal(-1) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1, 2, -1) } func TestXSWAPBad2(t *testing.T) { prog := makeProgram(opcode.XSWAP) - vm := load(prog) - vm.estack.PushVal(1) - vm.estack.PushVal(2) - vm.estack.PushVal(3) - vm.estack.PushVal(4) - vm.estack.PushVal(4) - checkVMFailed(t, vm) + runWithArgs(t, prog, nil, 1, 2, 3, 4, 4) } func TestDupInt(t *testing.T) { From 905f5f3047dfe63fe3c7aaaac383cfacec24f8e1 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Thu, 30 Apr 2020 15:48:51 +0300 Subject: [PATCH 5/5] *: go mod tidy --- go.sum | 8 -------- 1 file changed, 8 deletions(-) diff --git a/go.sum b/go.sum index 68831bf15..9747c253e 100644 --- a/go.sum +++ b/go.sum @@ -129,16 +129,8 @@ github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a h1:ajvxgEe9qY4vvoSm github.com/nspcc-dev/dbft v0.0.0-20200117124306-478e5cfbf03a/go.mod h1:/YFK+XOxxg0Bfm6P92lY5eDSLYfp06XOdL8KAVgXjVk= github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1 h1:yEx9WznS+rjE0jl0dLujCxuZSIb+UTjF+005TJu/nNI= github.com/nspcc-dev/dbft v0.0.0-20200219114139-199d286ed6c1/go.mod h1:O0qtn62prQSqizzoagHmuuKoz8QMkU3SzBoKdEvm3aQ= -github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682 h1:63OWUolW4GcjJR7cThq8hLnMLTwL+sjO3Qf4fo4sx8w= -github.com/nspcc-dev/dbft v0.0.0-20200303183127-36d3da79c682/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= github.com/nspcc-dev/dbft v0.0.0-20200427132226-05feeca847dd h1:4XKbXahJWlhjVx2cETQz9edHQfe3BQ2JjNdvSKFBelY= github.com/nspcc-dev/dbft v0.0.0-20200427132226-05feeca847dd/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-15a7927772a4 h1:3cFSp4v2u9+S7K1GdLUOP1680EiGEHSBvSI6G2n8XzY= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-15a7927772a4/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-342f23599814 h1:iNqBioi0RU2VX9UiGl/GfQKBbZrDWq5KSxQG+dgTaqo= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-342f23599814/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-660464796c11 h1:sledsmRo0wzgWNCZir5/CeM0PjhHVP8khnGtOfBCFWk= -github.com/nspcc-dev/dbft v0.0.0-20200427132226-660464796c11/go.mod h1:1FYQXSbb6/9HQIkoF8XO7W/S8N7AZRkBsgwbcXRvk0E= github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg= github.com/nspcc-dev/neofs-crypto v0.2.0 h1:ftN+59WqxSWz/RCgXYOfhmltOOqU+udsNQSvN6wkFck= github.com/nspcc-dev/neofs-crypto v0.2.0/go.mod h1:F/96fUzPM3wR+UGsPi3faVNmFlA9KAEAUQR7dMxZmNA=