-
Notifications
You must be signed in to change notification settings - Fork 175
/
script.go
91 lines (74 loc) · 1.82 KB
/
script.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
package fvm
import (
"github.com/onflow/cadence"
"github.com/onflow/cadence/runtime"
"github.com/onflow/flow-go/fvm/state"
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/model/hash"
)
func Script(code []byte) *ScriptProcedure {
scriptHash := hash.DefaultHasher.ComputeHash(code)
return &ScriptProcedure{
Script: code,
ID: flow.HashToID(scriptHash),
}
}
type ScriptProcedure struct {
ID flow.Identifier
Script []byte
Arguments [][]byte
Value cadence.Value
Logs []string
Events []flow.Event
// TODO: report gas consumption: https://github.com/dapperlabs/flow-go/issues/4139
GasUsed uint64
Err Error
}
type ScriptProcessor interface {
Process(*VirtualMachine, Context, *ScriptProcedure, state.Ledger) error
}
func (proc *ScriptProcedure) WithArguments(args ...[]byte) *ScriptProcedure {
return &ScriptProcedure{
ID: proc.ID,
Script: proc.Script,
Arguments: args,
}
}
func (proc *ScriptProcedure) Run(vm *VirtualMachine, ctx Context, ledger state.Ledger) error {
for _, p := range ctx.ScriptProcessors {
err := p.Process(vm, ctx, proc, ledger)
vmErr, fatalErr := handleError(err)
if fatalErr != nil {
return fatalErr
}
if vmErr != nil {
proc.Err = vmErr
return nil
}
}
return nil
}
type ScriptInvocator struct{}
func NewScriptInvocator() ScriptInvocator {
return ScriptInvocator{}
}
func (i ScriptInvocator) Process(
vm *VirtualMachine,
ctx Context,
proc *ScriptProcedure,
ledger state.Ledger,
) error {
env, err := newEnvironment(ctx, ledger)
if err != nil {
return err
}
location := runtime.ScriptLocation(proc.ID[:])
value, err := vm.Runtime.ExecuteScript(proc.Script, proc.Arguments, env, location)
if err != nil {
return err
}
proc.Value = value
proc.Logs = env.getLogs()
proc.Events = env.Events()
return nil
}