OSDN Git Service

Merge pull request #201 from Bytom/v0.1
[bytom/vapor.git] / vendor / github.com / bytom / protocol / vm / control_test.go
diff --git a/vendor/github.com/bytom/protocol/vm/control_test.go b/vendor/github.com/bytom/protocol/vm/control_test.go
new file mode 100644 (file)
index 0000000..2c134df
--- /dev/null
@@ -0,0 +1,220 @@
+package vm
+
+import (
+       "testing"
+
+       "github.com/bytom/testutil"
+)
+
+func TestControlOps(t *testing.T) {
+       type testStruct struct {
+               op      Op
+               startVM *virtualMachine
+               wantErr error
+               wantVM  *virtualMachine
+       }
+       cases := []testStruct{{
+               op: OP_JUMP,
+               startVM: &virtualMachine{
+                       runLimit: 50000,
+                       pc:       0,
+                       nextPC:   1,
+                       data:     []byte{0x05, 0x00, 0x00, 0x00},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit: 49999,
+                       pc:       0,
+                       nextPC:   5,
+                       data:     []byte{0x05, 0x00, 0x00, 0x00},
+               },
+       }, {
+               op: OP_JUMP,
+               startVM: &virtualMachine{
+                       runLimit: 50000,
+                       pc:       0,
+                       nextPC:   1,
+                       data:     []byte{0xff, 0xff, 0xff, 0xff},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit: 49999,
+                       pc:       0,
+                       nextPC:   4294967295,
+                       data:     []byte{0xff, 0xff, 0xff, 0xff},
+               },
+       }, {
+               op: OP_JUMPIF,
+               startVM: &virtualMachine{
+                       runLimit:     50000,
+                       pc:           0,
+                       nextPC:       1,
+                       deferredCost: 0,
+                       dataStack:    [][]byte{{1}},
+                       data:         []byte{0x05, 0x00, 0x00, 0x00},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit:     49999,
+                       pc:           0,
+                       nextPC:       5,
+                       deferredCost: -9,
+                       dataStack:    [][]byte{},
+                       data:         []byte{0x05, 0x00, 0x00, 0x00},
+               },
+       }, {
+               op: OP_JUMPIF,
+               startVM: &virtualMachine{
+                       runLimit:     50000,
+                       pc:           0,
+                       nextPC:       1,
+                       deferredCost: 0,
+                       dataStack:    [][]byte{{}},
+                       data:         []byte{0x05, 0x00, 0x00, 0x00},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit:     49999,
+                       pc:           0,
+                       nextPC:       1,
+                       deferredCost: -8,
+                       dataStack:    [][]byte{},
+                       data:         []byte{0x05, 0x00, 0x00, 0x00},
+               },
+       }, {
+               op: OP_VERIFY,
+               startVM: &virtualMachine{
+                       pc:           0,
+                       runLimit:     50000,
+                       deferredCost: 0,
+                       dataStack:    [][]byte{{1}},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit:     49999,
+                       deferredCost: -9,
+                       dataStack:    [][]byte{},
+               },
+       }, {
+               op: OP_VERIFY,
+               startVM: &virtualMachine{
+                       runLimit:     50000,
+                       deferredCost: 0,
+                       dataStack:    [][]byte{{1, 1}},
+               },
+               wantErr: nil,
+               wantVM: &virtualMachine{
+                       runLimit:     49999,
+                       deferredCost: -10,
+                       dataStack:    [][]byte{},
+               },
+       }, {
+               op: OP_VERIFY,
+               startVM: &virtualMachine{
+                       runLimit:     50000,
+                       deferredCost: 0,
+                       dataStack:    [][]byte{{}},
+               },
+               wantErr: ErrVerifyFailed,
+       }, {
+               startVM: &virtualMachine{runLimit: 50000},
+               op:      OP_FAIL,
+               wantErr: ErrReturn,
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{}, {byte(OP_TRUE)}, {}},
+               },
+               wantVM: &virtualMachine{
+                       runLimit:     0,
+                       deferredCost: -49951,
+                       dataStack:    [][]byte{{1}},
+               },
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{}, {}, {}},
+               },
+               wantVM: &virtualMachine{
+                       runLimit:     0,
+                       deferredCost: -49952,
+                       dataStack:    [][]byte{{}},
+               },
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{}, {byte(OP_FAIL)}, {}},
+               },
+               wantVM: &virtualMachine{
+                       runLimit:     0,
+                       deferredCost: -49952,
+                       dataStack:    [][]byte{{}},
+               },
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{}, {}, Int64Bytes(-1)},
+               },
+               wantErr: ErrBadValue,
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{}, {}, Int64Bytes(50000)},
+               },
+               wantErr: ErrRunLimitExceeded,
+       }, {
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{0x05}, {0x07}, {0x02}, {byte(OP_ADD), byte(OP_12), byte(OP_NUMEQUAL)}, {}},
+               },
+               wantVM: &virtualMachine{
+                       deferredCost: -49968,
+                       dataStack:    [][]byte{{0x01}},
+               },
+       }, {
+               // stack underflow in child vm should produce false result in parent vm
+               op: OP_CHECKPREDICATE,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{0x05}, {0x07}, {0x01}, {byte(OP_ADD), byte(OP_DATA_12), byte(OP_NUMEQUAL)}, {}},
+               },
+               wantVM: &virtualMachine{
+                       deferredCost: -49954,
+                       dataStack:    [][]byte{{0x05}, {}},
+               },
+       }}
+
+       limitChecks := []Op{
+               OP_CHECKPREDICATE, OP_VERIFY, OP_FAIL,
+       }
+
+       for _, op := range limitChecks {
+               cases = append(cases, testStruct{
+                       op:      op,
+                       startVM: &virtualMachine{runLimit: 0},
+                       wantErr: ErrRunLimitExceeded,
+               })
+       }
+
+       for i, c := range cases {
+               err := ops[c.op].fn(c.startVM)
+
+               if err != c.wantErr {
+                       t.Errorf("case %d, op %s: got err = %v want %v", i, c.op.String(), err, c.wantErr)
+                       continue
+               }
+               if c.wantErr != nil {
+                       continue
+               }
+
+               if !testutil.DeepEqual(c.startVM, c.wantVM) {
+                       t.Errorf("case %d, op %s: unexpected vm result\n\tgot:  %+v\n\twant: %+v\n", i, c.op.String(), c.startVM, c.wantVM)
+               }
+       }
+}