From baf9d2b76850fb184f30680a06704d996d999468 Mon Sep 17 00:00:00 2001 From: BlockChainDev Date: Fri, 15 Mar 2019 22:42:35 +0000 Subject: [PATCH] - Add test for math `Add` opcode - basic opcode execution --- pkg/vm/state.go | 10 ++++++++++ pkg/vm/vm.go | 38 ++++++++++++++++++++++++++++++++++++ pkg/vm/vm_ops_maths_test.go | 39 +++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 pkg/vm/state.go create mode 100644 pkg/vm/vm.go create mode 100644 pkg/vm/vm_ops_maths_test.go diff --git a/pkg/vm/state.go b/pkg/vm/state.go new file mode 100644 index 000000000..4090ec86e --- /dev/null +++ b/pkg/vm/state.go @@ -0,0 +1,10 @@ +package vm + +type vmstate byte + +const ( + NONE = 0 + HALT = 1 << 0 + FAULT = 1 << 1 + BREAK = 1 << 2 +) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go new file mode 100644 index 000000000..1793be031 --- /dev/null +++ b/pkg/vm/vm.go @@ -0,0 +1,38 @@ +package vm + +import ( + "fmt" + + "github.com/CityOfZion/neo-go/pkg/vm/stack" +) + +// VM represents an instance of a Neo Virtual Machine +type VM struct { + InvocationStack stack.Invocation + state vmstate +} + +//NewVM loads in a script +// uses the script to initiate a Context object +// pushes the context to the invocation stack +func NewVM(script []byte) *VM { + ctx := stack.NewContext(script) + v := &VM{ + state: NONE, + } + v.InvocationStack.Push(ctx) + return v +} + +// ExecuteOp will execute one opcode for a given context +func (v *VM) ExecuteOp(op stack.Instruction, ctx *stack.Context) error { + handleOp, ok := opFunc[op] + if !ok { + return fmt.Errorf("unknown opcode entered %v", op) + } + err := handleOp(ctx, &v.InvocationStack) + if err != nil { + return err + } + return nil +} diff --git a/pkg/vm/vm_ops_maths_test.go b/pkg/vm/vm_ops_maths_test.go new file mode 100644 index 000000000..a9d80373a --- /dev/null +++ b/pkg/vm/vm_ops_maths_test.go @@ -0,0 +1,39 @@ +package vm + +import ( + "math/big" + "testing" + + "github.com/CityOfZion/neo-go/pkg/vm/stack" + "github.com/stretchr/testify/assert" +) + +func TestAddOp(t *testing.T) { + + v := VM{} + + a, err := stack.NewInt(big.NewInt(20)) + if err != nil { + t.Fail() + } + b, err := stack.NewInt(big.NewInt(23)) + if err != nil { + t.Fail() + } + + ctx := stack.NewContext([]byte{}) + ctx.Estack.Push(a).Push(b) + + v.ExecuteOp(stack.ADD, ctx) + + // Stack should have one item + assert.Equal(t, 1, ctx.Estack.Len()) + + item, err := ctx.Estack.PopInt() + if err != nil { + t.Fail() + } + + assert.Equal(t, int64(43), item.Value().Int64()) + +}