lotus/chain/actors/manifest.go

160 lines
3.7 KiB
Go
Raw Normal View History

2022-04-04 11:14:27 +00:00
package actors
import (
"context"
2022-04-08 00:03:07 +00:00
"strings"
"sync"
2022-04-04 11:14:27 +00:00
"github.com/ipfs/go-cid"
2022-06-14 15:00:51 +00:00
cbor "github.com/ipfs/go-ipld-cbor"
2022-04-04 11:14:27 +00:00
"golang.org/x/xerrors"
2022-06-14 15:00:51 +00:00
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/lotus/chain/actors/adt"
2022-04-04 11:14:27 +00:00
)
var manifestCids map[Version]cid.Cid = make(map[Version]cid.Cid)
var manifests map[Version]map[string]cid.Cid = make(map[Version]map[string]cid.Cid)
var actorMeta map[cid.Cid]actorEntry = make(map[cid.Cid]actorEntry)
2022-04-04 11:14:27 +00:00
2022-05-16 23:43:06 +00:00
const (
AccountKey = "account"
CronKey = "cron"
InitKey = "init"
MarketKey = "storagemarket"
MinerKey = "storageminer"
MultisigKey = "multisig"
PaychKey = "paymentchannel"
PowerKey = "storagepower"
RewardKey = "reward"
SystemKey = "system"
VerifregKey = "verifiedregistry"
)
2022-04-20 21:34:28 +00:00
2022-05-30 18:51:59 +00:00
func GetBuiltinActorsKeys() []string {
return []string{
AccountKey,
CronKey,
InitKey,
MarketKey,
MinerKey,
MultisigKey,
PaychKey,
PowerKey,
RewardKey,
SystemKey,
VerifregKey,
}
}
var (
manifestMx sync.RWMutex
)
2022-04-04 11:14:27 +00:00
type actorEntry struct {
name string
version Version
}
// ClearManifest clears all known manifests. This is usually used in tests that need to switch networks.
func ClearManifests() {
2022-04-06 08:25:46 +00:00
manifestMx.Lock()
defer manifestMx.Unlock()
manifestCids = make(map[Version]cid.Cid)
manifests = make(map[Version]map[string]cid.Cid)
actorMeta = make(map[cid.Cid]actorEntry)
}
// RegisterManifest registers an actors manifest with lotus.
func RegisterManifest(av Version, manifestCid cid.Cid, entries map[string]cid.Cid) {
manifestMx.Lock()
defer manifestMx.Unlock()
2022-05-18 17:14:42 +00:00
2022-04-06 08:25:46 +00:00
manifestCids[av] = manifestCid
manifests[av] = entries
for name, c := range entries {
actorMeta[c] = actorEntry{name: name, version: av}
}
2022-04-06 08:25:46 +00:00
}
// GetManifest gets a loaded manifest.
2022-04-06 08:25:46 +00:00
func GetManifest(av Version) (cid.Cid, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
2022-04-06 08:25:46 +00:00
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) {
2022-04-04 11:14:27 +00:00
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)
}
2022-04-04 11:14:27 +00:00
if err := mf.Load(ctx, adtStore); err != nil {
return nil, xerrors.Errorf("error loading manifest (cid: %s): %w", mfCid, err)
}
2022-04-04 11:14:27 +00:00
actorKeys := GetBuiltinActorsKeys() // TODO: we should be able to enumerate manifests directly.
metadata := make(map[string]cid.Cid, len(actorKeys))
for _, name := range actorKeys {
if c, ok := mf.Get(name); ok {
metadata[name] = c
2022-04-04 11:14:27 +00:00
}
}
return metadata, nil
2022-04-04 11:14:27 +00:00
}
2022-06-29 15:46:51 +00:00
// 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) {
2022-06-28 22:42:58 +00:00
var mf manifest.Manifest
if err := adtStore.Get(ctx, mfCid, &mf); err != nil {
return nil, xerrors.Errorf("error reading manifest: %w", err)
}
2022-06-29 15:46:51 +00:00
if err := mf.Load(ctx, adtStore); err != nil {
return nil, xerrors.Errorf("error loading manifest entries data: %w", err)
2022-06-28 22:42:58 +00:00
}
2022-06-29 15:46:51 +00:00
return &mf, nil
2022-06-28 22:42:58 +00:00
}
2022-06-23 18:05:20 +00:00
// GetActorCodeID looks up a builtin actor's code CID by actor version and canonical actor name.
2022-04-04 11:14:27 +00:00
func GetActorCodeID(av Version, name string) (cid.Cid, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
c, ok := manifests[av][name]
return c, ok
2022-04-04 11:14:27 +00:00
}
func GetActorMetaByCode(c cid.Cid) (string, Version, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
2022-04-04 11:14:27 +00:00
entry, ok := actorMeta[c]
if !ok {
return "", -1, false
}
return entry.name, entry.version, true
}
2022-04-08 00:03:07 +00:00
func CanonicalName(name string) string {
idx := strings.LastIndex(name, "/")
if idx >= 0 {
return name[idx+1:]
}
return name
}