-
Notifications
You must be signed in to change notification settings - Fork 1
/
runner.go
139 lines (117 loc) · 3.43 KB
/
runner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package run
import (
"context"
"errors"
runtime "github.com/artela-network/aspect-runtime/types"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/artela-network/aspect-core/djpm/run/api"
"google.golang.org/protobuf/proto"
"github.com/artela-network/aspect-core/types"
)
type Runner struct {
ctx context.Context
vmKey string
vm runtime.AspectRuntime
// fns *runtime.HostAPIRegistry
registry *api.Registry
code []byte
commit bool
logger runtime.Logger
}
func NewRunner(ctx context.Context, logger runtime.Logger, aspID string, aspVer uint64, code []byte, commit bool) (*Runner, error) {
aspectId := common.HexToAddress(aspID)
registry := api.NewRegistry(ctx, aspectId, aspVer)
key, vm, err := types.RunnerPool(commit).Runtime(ctx, logger, code, registry.HostApis())
if err != nil {
return nil, err
}
return &Runner{
ctx: ctx,
logger: logger,
vmKey: key,
vm: vm,
registry: registry,
code: code,
commit: commit,
}, nil
}
func (r *Runner) Return() {
r.registry.Destroy()
types.RunnerPool(r.commit).Return(r.vmKey, r.vm)
}
func (r *Runner) JoinPoint(name types.PointCut, gas uint64, blockNumber int64, contractAddr *common.Address, txRequest proto.Message) ([]byte, uint64, error) {
if r.vm == nil {
return nil, gas, errors.New("runner not init")
}
// turn inputBytes into bytes
reqData, err := proto.Marshal(txRequest)
if err != nil {
return nil, gas, err
}
revertMsg := ""
errorFunc := func(msg string) {
revertMsg = msg
}
// for get aspect Error message
r.registry.SetErrCallback(errorFunc)
r.registry.SetRunnerContext(string(name), blockNumber, gas, contractAddr)
res, leftover, err := r.vm.Call(api.APIEntrance, int64(gas), string(name), reqData)
if err != nil {
if !strings.EqualFold(revertMsg, "") {
return []byte(revertMsg), gas, errors.New(revertMsg)
}
return nil, uint64(leftover), err
}
if res == nil {
return nil, uint64(leftover), nil
}
resData, ok := res.([]byte)
if !ok {
return nil, gas, errors.New("read output failed, return value is not byte array")
}
return resData, uint64(leftover), nil
}
func (r *Runner) IsOwner(blockNumber int64, gas uint64, contractAddr *common.Address, sender []byte) (bool, error) {
if r.vm == nil {
return false, errors.New("vm not init")
}
revertMsg := ""
callback := func(msg string) {
revertMsg = msg
}
r.registry.SetErrCallback(callback)
r.registry.SetRunnerContext("isOwner", blockNumber, gas, contractAddr)
// TODO: no gas refund for aspect for now, add later
res, _, err := r.vm.Call(api.APIEntrance, int64(gas), "isOwner", sender)
if err != nil {
if !strings.EqualFold(revertMsg, "") {
return false, errors.New(revertMsg)
}
return false, err
}
return res.(bool), nil
}
func (r *Runner) Gas() uint64 {
return r.registry.RunnerContext().Gas
}
func (r *Runner) ExecFunc(funcName string, blockNumber int64, gas uint64, contractAddr *common.Address, args ...interface{}) (interface{}, error) {
if r.vm == nil {
return false, errors.New("run not init")
}
revertMsg := ""
callback := func(msg string) {
revertMsg = msg
}
r.registry.SetErrCallback(callback)
r.registry.SetRunnerContext(funcName, blockNumber, gas, contractAddr)
// TODO: no gas refund for aspect for now, add later
res, _, err := r.vm.Call(funcName, int64(gas), args...)
if err != nil {
if !strings.EqualFold(revertMsg, "") {
return false, errors.New(revertMsg)
}
return nil, err
}
return res, nil
}