-
Notifications
You must be signed in to change notification settings - Fork 179
/
fvm.go
80 lines (66 loc) · 2.22 KB
/
fvm.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
package fvm
import (
"github.com/onflow/cadence/runtime"
"github.com/rs/zerolog"
"github.com/onflow/flow-go/fvm/state"
"github.com/onflow/flow-go/model/flow"
)
// An Procedure is an operation (or set of operations) that reads or writes ledger state.
type Procedure interface {
Run(vm *VirtualMachine, ctx Context, st *state.State) error
}
// A VirtualMachine augments the Cadence runtime with Flow host functionality.
type VirtualMachine struct {
Runtime runtime.Runtime
}
// New creates a new virtual machine instance with the provided runtime.
func New(rt runtime.Runtime) *VirtualMachine {
return &VirtualMachine{
Runtime: rt,
}
}
// Run runs a procedure against a ledger in the given context.
func (vm *VirtualMachine) Run(ctx Context, proc Procedure, ledger state.Ledger) error {
st := state.NewState(ledger,
state.WithMaxKeySizeAllowed(ctx.MaxStateKeySize),
state.WithMaxValueSizeAllowed(ctx.MaxStateValueSize),
state.WithMaxInteractionSizeAllowed(ctx.MaxStateInteractionSize))
err := proc.Run(vm, ctx, st)
if err != nil {
return err
}
return st.Commit()
}
// GetAccount returns an account by address or an error if none exists.
func (vm *VirtualMachine) GetAccount(ctx Context, address flow.Address, ledger state.Ledger) (*flow.Account, error) {
st := state.NewState(ledger,
state.WithMaxKeySizeAllowed(ctx.MaxStateKeySize),
state.WithMaxValueSizeAllowed(ctx.MaxStateValueSize),
state.WithMaxInteractionSizeAllowed(ctx.MaxStateInteractionSize))
account, err := getAccount(vm, ctx, st, address)
if err != nil {
// TODO: wrap error
return nil, err
}
err = st.Commit()
if err != nil {
// TODO: wrap error
return nil, err
}
return account, nil
}
// invokeMetaTransaction invokes a meta transaction inside the context of an outer transaction.
//
// Errors that occur in a meta transaction are propagated as a single error that can be
// captured by the Cadence runtime and eventually disambiguated by the parent context.
func (vm *VirtualMachine) invokeMetaTransaction(ctx Context, tx *TransactionProcedure, st *state.State) error {
invocator := NewTransactionInvocator(zerolog.Nop())
err := invocator.Process(vm, ctx, tx, st)
if err != nil {
return err
}
if tx.Err != nil {
return tx.Err
}
return nil
}