2022-04-04 11:14:27 +00:00
|
|
|
package actors
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2022-04-08 00:03:07 +00:00
|
|
|
"strings"
|
2022-04-04 17:11:19 +00:00
|
|
|
"sync"
|
2022-04-04 11:14:27 +00:00
|
|
|
|
2022-06-15 10:06:22 +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-09-06 15:49:29 +00:00
|
|
|
actorstypes "github.com/filecoin-project/go-state-types/actors"
|
2022-06-14 15:00:51 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/manifest"
|
|
|
|
|
2022-05-26 19:14:29 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/actors/adt"
|
2022-04-04 11:14:27 +00:00
|
|
|
)
|
|
|
|
|
2022-12-13 23:02:34 +00:00
|
|
|
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)
|
2022-05-30 18:51:59 +00:00
|
|
|
|
2022-04-04 17:11:19 +00:00
|
|
|
var (
|
2022-04-21 10:53:30 +00:00
|
|
|
manifestMx sync.RWMutex
|
2022-04-04 17:11:19 +00:00
|
|
|
)
|
|
|
|
|
2022-04-04 11:14:27 +00:00
|
|
|
type actorEntry struct {
|
|
|
|
name string
|
2022-09-06 15:49:29 +00:00
|
|
|
version actorstypes.Version
|
2022-04-04 11:14:27 +00:00
|
|
|
}
|
|
|
|
|
2022-09-21 19:51:28 +00:00
|
|
|
// ClearManifests clears all known manifests. This is usually used in tests that need to switch networks.
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
func ClearManifests() {
|
2022-04-06 08:25:46 +00:00
|
|
|
manifestMx.Lock()
|
|
|
|
defer manifestMx.Unlock()
|
|
|
|
|
2022-09-06 15:49:29 +00:00
|
|
|
manifestCids = make(map[actorstypes.Version]cid.Cid)
|
|
|
|
manifests = make(map[actorstypes.Version]map[string]cid.Cid)
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
actorMeta = make(map[cid.Cid]actorEntry)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RegisterManifest registers an actors manifest with lotus.
|
2022-09-06 15:49:29 +00:00
|
|
|
func RegisterManifest(av actorstypes.Version, manifestCid cid.Cid, entries map[string]cid.Cid) {
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
manifestMx.Lock()
|
|
|
|
defer manifestMx.Unlock()
|
2022-05-18 17:14:42 +00:00
|
|
|
|
2022-04-06 08:25:46 +00:00
|
|
|
manifestCids[av] = manifestCid
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
manifests[av] = entries
|
|
|
|
|
|
|
|
for name, c := range entries {
|
|
|
|
actorMeta[c] = actorEntry{name: name, version: av}
|
|
|
|
}
|
2022-04-06 08:25:46 +00:00
|
|
|
}
|
|
|
|
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
// GetManifest gets a loaded manifest.
|
2022-09-06 15:49:29 +00:00
|
|
|
func GetManifest(av actorstypes.Version) (cid.Cid, bool) {
|
2022-04-21 10:53:30 +00:00
|
|
|
manifestMx.RLock()
|
|
|
|
defer manifestMx.RUnlock()
|
2022-04-06 08:25:46 +00:00
|
|
|
|
|
|
|
c, ok := manifestCids[av]
|
|
|
|
return c, ok
|
|
|
|
}
|
|
|
|
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
// 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)
|
|
|
|
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
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
|
|
|
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +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
|
|
|
|
2022-09-21 19:51:28 +00:00
|
|
|
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
|
2022-04-04 11:14:27 +00:00
|
|
|
}
|
|
|
|
|
feat: refactor: actor bundling system (#8838)
1. Include the builtin-actors in the lotus source tree.
2. Embed the bundle on build instead of downloading at runtime.
3. Avoid reading the bundle whenever possible by including bundle
metadata (the bundle CID, the actor CIDs, etc.).
4. Remove everything related to dependency injection.
1. We're no longer downloading the bundle, so doing anything ahead
of time doesn't really help.
2. We register the manifests on init because, unfortunately, they're
global.
3. We explicitly load the current actors bundle in the genesis
state-tree method.
4. For testing, we just change the in-use bundle with a bit of a
hack. It's not great, but using dependency injection doesn't make
any sense either because, again, the manifest information is
global.
5. Remove the bundle.toml file. Bundles may be overridden by
specifying an override path in the parameters file, or an
environment variable.
fixes #8701
2022-06-13 17:15:00 +00:00
|
|
|
return metadata, nil
|
2022-04-04 11:14:27 +00:00
|
|
|
}
|
|
|
|
|
2022-06-29 16:54:14 +00:00
|
|
|
// GetActorCodeIDsFromManifest looks up all builtin actor's code CIDs by actor version for versions that have a manifest.
|
2022-09-06 15:49:29 +00:00
|
|
|
func GetActorCodeIDsFromManifest(av actorstypes.Version) (map[string]cid.Cid, bool) {
|
2022-06-28 16:39:19 +00:00
|
|
|
manifestMx.RLock()
|
|
|
|
defer manifestMx.RUnlock()
|
|
|
|
|
|
|
|
cids, ok := manifests[av]
|
|
|
|
return cids, ok
|
|
|
|
}
|
|
|
|
|
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-09-06 15:49:29 +00:00
|
|
|
func GetActorMetaByCode(c cid.Cid) (string, actorstypes.Version, bool) {
|
2022-04-21 10:53:30 +00:00
|
|
|
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
|
|
|
|
}
|