-
Notifications
You must be signed in to change notification settings - Fork 4
/
builtin.go
117 lines (97 loc) · 3.46 KB
/
builtin.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
// Package builtin is implementation of builtin contracts engine
package builtin
import (
"context"
errors "github.com/insolar/assured-ledger/ledger-core/vanilla/throw"
"github.com/insolar/assured-ledger/ledger-core/application/builtin"
"github.com/insolar/assured-ledger/ledger-core/insolar/contract"
"github.com/insolar/assured-ledger/ledger-core/reference"
"github.com/insolar/assured-ledger/ledger-core/runner/call"
"github.com/insolar/assured-ledger/ledger-core/runner/executor/common"
"github.com/insolar/assured-ledger/ledger-core/runner/executor/common/foundation"
"github.com/insolar/assured-ledger/ledger-core/vanilla/throw"
)
// Runner is a contract runner engine
type Runner struct {
Helper contract.ProxyHelper
DescriptorRegistry map[reference.Global]interface{}
CodeRegistry map[string]contract.Wrapper
CodeRefRegistry map[reference.Global]string
ClassRefRegistry map[reference.Global]string
}
// New is an constructor
func New(stub common.RunnerRPCStub) *Runner {
descriptorRegistry := make(map[reference.Global]interface{})
for _, classDescriptor := range builtin.InitializeClassDescriptors() {
descriptorRegistry[classDescriptor.HeadRef()] = classDescriptor
}
for _, codeDescriptor := range builtin.InitializeCodeDescriptors() {
descriptorRegistry[codeDescriptor.Ref()] = codeDescriptor
}
return &Runner{
Helper: NewProxyHelper(stub),
DescriptorRegistry: descriptorRegistry,
CodeRegistry: builtin.InitializeContractMethods(),
CodeRefRegistry: builtin.InitializeCodeRefs(),
ClassRefRegistry: builtin.InitializeClassRefs(),
}
}
func (r *Runner) CallConstructor(
_ context.Context,
callCtx *call.LogicContext,
codeRef reference.Global,
name string,
args []byte,
) ([]byte, []byte, error) {
foundation.SetLogicalContext(callCtx)
defer foundation.ClearContext()
contractName, ok := r.CodeRefRegistry[codeRef]
if !ok {
return nil, nil, errors.New("failed to find contract with reference")
}
contract := r.CodeRegistry[contractName]
constructorFunc, ok := contract.Constructors[name]
if !ok {
return nil, nil, errors.New("failed to find contracts constructor")
}
return constructorFunc(callCtx.Callee, args, r.Helper)
}
func (r *Runner) CallMethod(
_ context.Context,
callCtx *call.LogicContext,
codeRef reference.Global,
data []byte,
method string,
args []byte,
) ([]byte, []byte, error) {
foundation.SetLogicalContext(callCtx)
defer foundation.ClearContext()
contractName, ok := r.CodeRefRegistry[codeRef]
if !ok {
return nil, nil, errors.New("failed to find contract with reference")
}
contract := r.CodeRegistry[contractName]
methodObject, ok := contract.Methods[method]
if !ok {
return nil, nil, errors.New("failed to find contracts method")
}
return methodObject.Func(data, args, r.Helper)
}
func (r *Runner) ClassifyMethod(_ context.Context,
codeRef reference.Global,
method string) (contract.MethodIsolation, error) {
contractName, ok := r.CodeRefRegistry[codeRef]
if !ok {
errInfo := struct{ Reference reference.Global }{Reference: codeRef}
return contract.MethodIsolation{}, throw.E("failed to find contract with reference", errInfo)
}
contractObj := r.CodeRegistry[contractName]
methodObject, ok := contractObj.Methods[method]
if !ok {
return contract.MethodIsolation{}, throw.E("failed to find contracts method")
}
return methodObject.Isolation, nil
}
func (r *Runner) GetDescriptor(ref reference.Global) (interface{}, error) {
return r.DescriptorRegistry[ref], nil
}