OSDN Git Service

feat: add processIssuing (#152)
[bytom/vapor.git] / vendor / github.com / bytom / 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 < 0 {
53                 n = l
54         }
55         if n > l {
56                 return ErrDataStackUnderflow
57         }
58         if limit == 0 {
59                 limit = vm.runLimit
60         }
61         err = vm.applyCost(limit)
62         if err != nil {
63                 return err
64         }
65
66         childVM := virtualMachine{
67                 context:   vm.context,
68                 program:   predicate,
69                 runLimit:  limit,
70                 depth:     vm.depth + 1,
71                 dataStack: append([][]byte{}, vm.dataStack[l-n:]...),
72         }
73         vm.dataStack = vm.dataStack[:l-n]
74
75         childErr := childVM.run()
76
77         vm.deferCost(-childVM.runLimit)
78         vm.deferCost(-stackCost(childVM.dataStack))
79         vm.deferCost(-stackCost(childVM.altStack))
80
81         return vm.pushBool(childErr == nil && !childVM.falseResult(), true)
82 }
83
84 func opJump(vm *virtualMachine) error {
85         err := vm.applyCost(1)
86         if err != nil {
87                 return err
88         }
89         address := binary.LittleEndian.Uint32(vm.data)
90         vm.nextPC = address
91         return nil
92 }
93
94 func opJumpIf(vm *virtualMachine) error {
95         err := vm.applyCost(1)
96         if err != nil {
97                 return err
98         }
99         p, err := vm.pop(true)
100         if err != nil {
101                 return err
102         }
103         if AsBool(p) {
104                 address := binary.LittleEndian.Uint32(vm.data)
105                 vm.nextPC = address
106         }
107         return nil
108 }