OSDN Git Service

Added blockchain struct.
[bytom/bytom.git] / protocol / vm / control.go
1 package vm
2
3 import (
4         "encoding/binary"
5 )
6
7 func opVerify(vm *virtualMachine) error {
8         err := vm.applyCost(1)
9         if err != nil {
10                 return err
11         }
12         p, err := vm.pop(true)
13         if err != nil {
14                 return err
15         }
16         if AsBool(p) {
17                 return nil
18         }
19         return ErrVerifyFailed
20 }
21
22 func opFail(vm *virtualMachine) error {
23         err := vm.applyCost(1)
24         if err != nil {
25                 return err
26         }
27         return ErrReturn
28 }
29
30 func opCheckPredicate(vm *virtualMachine) error {
31         err := vm.applyCost(256)
32         if err != nil {
33                 return err
34         }
35         vm.deferCost(-256 + 64) // get most of that cost back at the end
36         limit, err := vm.popInt64(true)
37         if err != nil {
38                 return err
39         }
40         predicate, err := vm.pop(true)
41         if err != nil {
42                 return err
43         }
44         n, err := vm.popInt64(true)
45         if err != nil {
46                 return err
47         }
48         if limit < 0 {
49                 return ErrBadValue
50         }
51         l := int64(len(vm.dataStack))
52         if n > l {
53                 return ErrDataStackUnderflow
54         }
55         if limit == 0 {
56                 limit = vm.runLimit
57         }
58         err = vm.applyCost(limit)
59         if err != nil {
60                 return err
61         }
62
63         childVM := virtualMachine{
64                 context:   vm.context,
65                 program:   predicate,
66                 runLimit:  limit,
67                 depth:     vm.depth + 1,
68                 dataStack: append([][]byte{}, vm.dataStack[l-n:]...),
69         }
70         vm.dataStack = vm.dataStack[:l-n]
71
72         childErr := childVM.run()
73
74         vm.deferCost(-childVM.runLimit)
75         vm.deferCost(-stackCost(childVM.dataStack))
76         vm.deferCost(-stackCost(childVM.altStack))
77
78         return vm.pushBool(childErr == nil && !childVM.falseResult(), true)
79 }
80
81 func opJump(vm *virtualMachine) error {
82         err := vm.applyCost(1)
83         if err != nil {
84                 return err
85         }
86         address := binary.LittleEndian.Uint32(vm.data)
87         vm.nextPC = address
88         return nil
89 }
90
91 func opJumpIf(vm *virtualMachine) error {
92         err := vm.applyCost(1)
93         if err != nil {
94                 return err
95         }
96         p, err := vm.pop(true)
97         if err != nil {
98                 return err
99         }
100         if AsBool(p) {
101                 address := binary.LittleEndian.Uint32(vm.data)
102                 vm.nextPC = address
103         }
104         return nil
105 }