-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
manifest.go
132 lines (101 loc) · 3.4 KB
/
manifest.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
package actors
import (
"context"
"strings"
"sync"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"golang.org/x/xerrors"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/lotus/chain/actors/adt"
)
var manifestCids = make(map[actorstypes.Version]cid.Cid)
var manifests = make(map[actorstypes.Version]map[string]cid.Cid)
var actorMeta = make(map[cid.Cid]actorEntry)
var (
manifestMx sync.RWMutex
)
type actorEntry struct {
name string
version actorstypes.Version
}
// ClearManifests clears all known manifests. This is usually used in tests that need to switch networks.
func ClearManifests() {
manifestMx.Lock()
defer manifestMx.Unlock()
manifestCids = make(map[actorstypes.Version]cid.Cid)
manifests = make(map[actorstypes.Version]map[string]cid.Cid)
actorMeta = make(map[cid.Cid]actorEntry)
}
// RegisterManifest registers an actors manifest with lotus.
func RegisterManifest(av actorstypes.Version, manifestCid cid.Cid, entries map[string]cid.Cid) {
manifestMx.Lock()
defer manifestMx.Unlock()
manifestCids[av] = manifestCid
manifests[av] = entries
for name, c := range entries {
actorMeta[c] = actorEntry{name: name, version: av}
}
}
// GetManifest gets a loaded manifest.
func GetManifest(av actorstypes.Version) (cid.Cid, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
c, ok := manifestCids[av]
return c, ok
}
// ReadManifest reads a manifest from a blockstore. It does not "add" it.
func ReadManifest(ctx context.Context, store cbor.IpldStore, mfCid cid.Cid) (map[string]cid.Cid, error) {
adtStore := adt.WrapStore(ctx, store)
var mf manifest.Manifest
if err := adtStore.Get(ctx, mfCid, &mf); err != nil {
return nil, xerrors.Errorf("error reading manifest (cid: %s): %w", mfCid, err)
}
if err := mf.Load(ctx, adtStore); err != nil {
return nil, xerrors.Errorf("error loading manifest (cid: %s): %w", mfCid, err)
}
var manifestData manifest.ManifestData
if err := store.Get(ctx, mf.Data, &manifestData); err != nil {
return nil, xerrors.Errorf("error loading manifest data: %w", err)
}
metadata := make(map[string]cid.Cid)
for _, entry := range manifestData.Entries {
metadata[entry.Name] = entry.Code
}
return metadata, nil
}
// GetActorCodeIDsFromManifest looks up all builtin actor's code CIDs by actor version for versions that have a manifest.
func GetActorCodeIDsFromManifest(av actorstypes.Version) (map[string]cid.Cid, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
cids, ok := manifests[av]
return cids, ok
}
// Given a Manifest CID, get the manifest from the store and Load data into its entries
func LoadManifest(ctx context.Context, mfCid cid.Cid, adtStore adt.Store) (*manifest.Manifest, error) {
var mf manifest.Manifest
if err := adtStore.Get(ctx, mfCid, &mf); err != nil {
return nil, xerrors.Errorf("error reading manifest: %w", err)
}
if err := mf.Load(ctx, adtStore); err != nil {
return nil, xerrors.Errorf("error loading manifest entries data: %w", err)
}
return &mf, nil
}
func GetActorMetaByCode(c cid.Cid) (string, actorstypes.Version, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
entry, ok := actorMeta[c]
if !ok {
return "", -1, false
}
return entry.name, entry.version, true
}
func CanonicalName(name string) string {
idx := strings.LastIndex(name, "/")
if idx >= 0 {
return name[idx+1:]
}
return name
}