lotus/chain/actors/manifest.go

162 lines
3.2 KiB
Go
Raw Normal View History

2022-04-04 11:14:27 +00:00
package actors
import (
"bytes"
2022-04-04 11:14:27 +00:00
"context"
2022-04-08 00:03:07 +00:00
"strings"
"sync"
2022-04-04 11:14:27 +00:00
2022-04-20 21:34:28 +00:00
"github.com/filecoin-project/go-state-types/manifest"
2022-04-04 11:14:27 +00:00
"golang.org/x/xerrors"
cid "github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
car "github.com/ipld/go-car"
2022-04-04 11:14:27 +00:00
"github.com/filecoin-project/lotus/blockstore"
2022-04-04 11:14:27 +00:00
"github.com/filecoin-project/lotus/chain/actors/adt"
)
2022-04-06 08:25:46 +00:00
var manifestCids map[Version]cid.Cid = map[Version]cid.Cid{
// TODO fill in manifest CIDs for v8 and upwards once these are fixed
2022-04-04 11:14:27 +00:00
}
var manifests map[Version]*manifest.Manifest
var actorMeta map[cid.Cid]actorEntry
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
var (
manifestMx sync.RWMutex
)
2022-04-04 11:14:27 +00:00
type actorEntry struct {
name string
version Version
}
2022-04-06 08:25:46 +00:00
func AddManifest(av Version, manifestCid cid.Cid) {
manifestMx.Lock()
defer manifestMx.Unlock()
manifestCids[av] = manifestCid
}
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
}
2022-04-04 11:14:27 +00:00
func LoadManifests(ctx context.Context, store cbor.IpldStore) error {
manifestMx.Lock()
defer manifestMx.Unlock()
return loadManifests(ctx, store)
}
func loadManifests(ctx context.Context, store cbor.IpldStore) error {
2022-04-04 11:14:27 +00:00
adtStore := adt.WrapStore(ctx, store)
manifests = make(map[Version]*manifest.Manifest)
actorMeta = make(map[cid.Cid]actorEntry)
2022-04-06 08:25:46 +00:00
for av, mfCid := range manifestCids {
2022-04-04 11:14:27 +00:00
mf := &manifest.Manifest{}
if err := adtStore.Get(ctx, mfCid, mf); err != nil {
return xerrors.Errorf("error reading manifest for network version %d (cid: %s): %w", av, mfCid, err)
}
if err := mf.Load(ctx, adtStore); err != nil {
return xerrors.Errorf("error loading manifest for network version %d: %w", av, err)
}
manifests[av] = mf
2022-04-20 21:34:28 +00:00
for _, name := range []string{
AccountKey,
CronKey,
InitKey,
MarketKey,
MinerKey,
MultisigKey,
PaychKey,
PowerKey,
RewardKey,
SystemKey,
VerifregKey,
} {
2022-04-04 11:14:27 +00:00
c, ok := mf.Get(name)
if ok {
actorMeta[c] = actorEntry{name: name, version: av}
}
}
}
return nil
}
func GetActorCodeID(av Version, name string) (cid.Cid, bool) {
manifestMx.RLock()
defer manifestMx.RUnlock()
2022-04-04 11:14:27 +00:00
mf, ok := manifests[av]
if ok {
return mf.Get(name)
}
return cid.Undef, false
}
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
}
func LoadBundle(ctx context.Context, bs blockstore.Blockstore, av Version, data []byte) error {
blobr := bytes.NewReader(data)
hdr, err := car.LoadCar(ctx, bs, blobr)
if err != nil {
return xerrors.Errorf("error loading builtin actors v%d bundle: %w", av, err)
}
2022-04-20 21:34:28 +00:00
// TODO: check that this only has one root?
manifestCid := hdr.Roots[0]
AddManifest(av, manifestCid)
return nil
}