-
Notifications
You must be signed in to change notification settings - Fork 179
/
view.go
98 lines (80 loc) · 2.73 KB
/
view.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
package state
import (
"golang.org/x/exp/slices"
"github.com/onflow/flow-go/fvm/meter"
"github.com/onflow/flow-go/model/flow"
)
type View interface {
NewChild() View
Finalize() *ExecutionSnapshot
Merge(child *ExecutionSnapshot) error
Storage
}
// Storage is the storage interface used by the virtual machine to read and
// write register values.
type Storage interface {
// TODO(patrick): remove once fvm.VM.Run() is deprecated
Peek(id flow.RegisterID) (flow.RegisterValue, error)
Set(id flow.RegisterID, value flow.RegisterValue) error
Get(id flow.RegisterID) (flow.RegisterValue, error)
DropChanges() error
}
type ExecutionSnapshot struct {
// Note that the ReadSet only include reads from the storage snapshot.
// Reads from the WriteSet are excluded from the ReadSet.
ReadSet map[flow.RegisterID]struct{}
WriteSet map[flow.RegisterID]flow.RegisterValue
// Note that the spock secret may be nil if the view does not support spock.
SpockSecret []byte
// Note that the meter may be nil if the view does not support metering.
*meter.Meter
}
// UpdatedRegisters returns all registers that were updated by this view.
// The returned entries are sorted by ids.
func (snapshot *ExecutionSnapshot) UpdatedRegisters() flow.RegisterEntries {
entries := make(flow.RegisterEntries, 0, len(snapshot.WriteSet))
for key, value := range snapshot.WriteSet {
entries = append(entries, flow.RegisterEntry{Key: key, Value: value})
}
slices.SortFunc(entries, func(a, b flow.RegisterEntry) bool {
return (a.Key.Owner < b.Key.Owner) ||
(a.Key.Owner == b.Key.Owner && a.Key.Key < b.Key.Key)
})
return entries
}
// UpdatedRegisterIDs returns all register ids that were updated by this
// view. The returned ids are unsorted.
func (snapshot *ExecutionSnapshot) UpdatedRegisterIDs() []flow.RegisterID {
ids := make([]flow.RegisterID, 0, len(snapshot.WriteSet))
for key := range snapshot.WriteSet {
ids = append(ids, key)
}
return ids
}
// ReadRegisterIDs returns a list of register ids that were read.
// The returned ids are unsorted
func (snapshot *ExecutionSnapshot) ReadRegisterIDs() []flow.RegisterID {
ret := make([]flow.RegisterID, 0, len(snapshot.ReadSet))
for k := range snapshot.ReadSet {
ret = append(ret, k)
}
return ret
}
// AllRegisterIDs returns all register ids that were read / write by this
// view. The returned ids are unsorted.
func (snapshot *ExecutionSnapshot) AllRegisterIDs() []flow.RegisterID {
set := make(
map[flow.RegisterID]struct{},
len(snapshot.ReadSet)+len(snapshot.WriteSet))
for reg := range snapshot.ReadSet {
set[reg] = struct{}{}
}
for reg := range snapshot.WriteSet {
set[reg] = struct{}{}
}
ret := make([]flow.RegisterID, 0, len(set))
for r := range set {
ret = append(ret, r)
}
return ret
}