diff --git a/pkg/vm/vm_ops.go b/pkg/vm/vm_ops.go index b73b6aa31..d50609462 100644 --- a/pkg/vm/vm_ops.go +++ b/pkg/vm/vm_ops.go @@ -5,6 +5,8 @@ import "github.com/CityOfZion/neo-go/pkg/vm/stack" type stackInfo func(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) var opFunc = map[stack.Instruction]stackInfo{ + stack.NUMEQUAL: NumEqual, + stack.NUMNOTEQUAL: NumNotEqual, stack.BOOLAND: BoolAnd, stack.BOOLOR: BoolOr, stack.LT: Lt, diff --git a/pkg/vm/vm_ops_maths.go b/pkg/vm/vm_ops_maths.go index d9a3a9bbc..e23a7a4a0 100644 --- a/pkg/vm/vm_ops_maths.go +++ b/pkg/vm/vm_ops_maths.go @@ -173,6 +173,38 @@ func Mul(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rst return NONE, nil } +// NumEqual pops two Items off of the stack and pushes a boolean to the stack +// whose value is true iff the the two Items are equal. +// Returns an error if either items cannot be casted to an integer. +func NumEqual(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) { + + operandA, operandB, err := popTwoIntegers(ctx) + if err != nil { + return FAULT, err + } + res := operandA.Equal(operandB) + + ctx.Estack.Push(stack.NewBoolean(res)) + + return NONE, nil +} + +// NumNotEqual pops two Items off of the stack and pushes a boolean to the stack +// whose value is true iff the two Items are not equal. +// Returns an error if either items cannot be casted to an integer. +func NumNotEqual(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) { + + operandA, operandB, err := popTwoIntegers(ctx) + if err != nil { + return FAULT, err + } + res := operandA.Equal(operandB) + + ctx.Estack.Push(stack.NewBoolean(!res)) + + return NONE, nil +} + // Abs pops an integer off of the stack and pushes its absolute value onto the stack. // Returns an error if the popped value is not an integer or if the absolute value cannot be taken func Abs(op stack.Instruction, ctx *stack.Context, istack *stack.Invocation, rstack *stack.RandomAccess) (Vmstate, error) { diff --git a/pkg/vm/vm_ops_maths_test.go b/pkg/vm/vm_ops_maths_test.go index 3d0163f47..b8478f29b 100644 --- a/pkg/vm/vm_ops_maths_test.go +++ b/pkg/vm/vm_ops_maths_test.go @@ -277,6 +277,64 @@ func TestNotOp(t *testing.T) { assert.Equal(t, true, item.Value()) } +func TestNumEqual(t *testing.T) { + + v := VM{} + + a, err := stack.NewInt(big.NewInt(6)) + if err != nil { + t.Fail() + } + b, err := stack.NewInt(big.NewInt(6)) + if err != nil { + t.Fail() + } + + ctx := stack.NewContext([]byte{}) + ctx.Estack.Push(a).Push(b) + + v.executeOp(stack.NUMEQUAL, ctx) + + // Stack should have one item + assert.Equal(t, 1, ctx.Estack.Len()) + + item, err := ctx.Estack.PopBoolean() + if err != nil { + t.Fail() + } + + assert.Equal(t, true, item.Value()) +} + +func TestNumNotEqual(t *testing.T) { + + v := VM{} + + a, err := stack.NewInt(big.NewInt(5)) + if err != nil { + t.Fail() + } + b, err := stack.NewInt(big.NewInt(6)) + if err != nil { + t.Fail() + } + + ctx := stack.NewContext([]byte{}) + ctx.Estack.Push(a).Push(b) + + v.executeOp(stack.NUMNOTEQUAL, ctx) + + // Stack should have one item + assert.Equal(t, 1, ctx.Estack.Len()) + + item, err := ctx.Estack.PopBoolean() + if err != nil { + t.Fail() + } + + assert.Equal(t, true, item.Value()) +} + func TestSignOp(t *testing.T) { v := VM{}