diff --git a/Makefile b/Makefile index f906dd1d6..73e7dda40 100644 --- a/Makefile +++ b/Makefile @@ -57,14 +57,6 @@ build/.update-modules: # end git modules -# builtin actor bundles -builtin-actor-bundles: - ./build/builtin-actors/fetch-bundles.sh - -BUILD_DEPS+=builtin-actor-bundles - -.PHONY: builtin-actor-bundles - ## MAIN BINARIES CLEAN+=build/.update-modules diff --git a/build/builtin-actors/README.md b/build/builtin-actors/README.md deleted file mode 100644 index 11625b261..000000000 --- a/build/builtin-actors/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains the builtin actors v8 bundle, to be emdedded in the binary. -To change your actor bundle, prior to fixing for nv16 upgrade, generate a bundle using the actor -bundler and place it in this directory, in a file named builtin-actors-v8.car diff --git a/build/builtin-actors/bundles.env b/build/builtin-actors/bundles.env deleted file mode 100644 index d9b1ab43e..000000000 --- a/build/builtin-actors/bundles.env +++ /dev/null @@ -1,2 +0,0 @@ -actors7_release="" -actors8_release=c718ae4f957b1806 diff --git a/build/builtin-actors/fetch-bundles.sh b/build/builtin-actors/fetch-bundles.sh deleted file mode 100755 index 66c1c2d6b..000000000 --- a/build/builtin-actors/fetch-bundles.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -set -e - -cd "$(dirname "$0")" - -. bundles.env - -die() { - echo "$1" - exit 1 -} - -fetch() { - ver=$1 - rel=$2 - - if [ ! -e $ver ]; then - mkdir $ver - fi - - if [ -e $ver/release ]; then - cur=$(cat $ver/release) - if [ $cur == $rel ]; then - return 0 - fi - fi - - for net in mainnet caterpillarnet butterflynet calibrationnet devnet testing testing-fake-proofs; do - fetch_bundle $ver $rel $net - done - - # remember the current release so that we don't have to hit github unless we have modified it - echo $rel > $ver/release -} - -fetch_bundle() { - ver=$1 - rel=$2 - net=$3 - - target=builtin-actors-$net.car - hash=builtin-actors-$net.sha256 - - pushd $ver - - # fetch the hash first and check if it matches what we (may) already have - curl -L --retry 3 https://github.com/filecoin-project/builtin-actors/releases/download/$rel/$hash -o $hash || die "error fetching hash for $ver/$net" - if [ -e $target ]; then - if (shasum -a 256 --check $hash); then - popd - return 0 - fi - fi - - # we don't have the (correct) bundle, fetch it - curl -L --retry 3 https://github.com/filecoin-project/builtin-actors/releases/download/$rel/$target -o $target || die "error fetching bundle for $ver/$net" - # verify - shasum -a 256 --check $hash || die "hash mismatch" - # all good - popd -} - -touch_bundles() { - ver=$1 - - if [ ! -e $ver ]; then - mkdir $ver - fi - - for net in mainnet caterpillarnet butterflynet calibrationnet devnet testing testing-fake-proofs; do - touch $ver/builtin-actors-$net.car - done -} - -if [ -n "$actors7_release" ]; then - fetch v7 "$actors7_release" -else - touch_bundles v7 -fi - -if [ -n "$actors8_release" ]; then - fetch v8 "$actors8_release" -else - touch_bundles v8 -fi diff --git a/build/builtin_actors.go b/build/builtin_actors.go new file mode 100644 index 000000000..e62b3fa21 --- /dev/null +++ b/build/builtin_actors.go @@ -0,0 +1,14 @@ +package build + +import ( + "github.com/filecoin-project/lotus/chain/actors" +) + +// TODO a nicer interface would be to embed (and parse) a toml file containing the releases +var BuiltinActorReleases map[actors.Version]string + +func init() { + BuiltinActorReleases = map[actors.Version]string{ + actors.Version8: "b71c2ec785aec23d", + } +} diff --git a/build/builtin_actors_2k.go b/build/builtin_actors_2k.go deleted file mode 100644 index 1dfee49dc..000000000 --- a/build/builtin_actors_2k.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build debug || 2k || testground -// +build debug 2k testground - -package build - -import ( - _ "embed" -) - -//go:embed builtin-actors/v8/builtin-actors-devnet.car -var actorsv8 []byte - -func BuiltinActorsV8Bundle() []byte { - return actorsv8 -} - -//go:embed builtin-actors/v7/builtin-actors-devnet.car -var actorsv7 []byte - -func BuiltinActorsV7Bundle() []byte { - return actorsv7 -} diff --git a/build/builtin_actors_butterfly.go b/build/builtin_actors_butterfly.go deleted file mode 100644 index d3d76e8f9..000000000 --- a/build/builtin_actors_butterfly.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build butterflynet -// +build butterflynet - -package build - -import ( - _ "embed" -) - -//go:embed builtin-actors/v8/builtin-actors-butterflynet.car -var actorsv8 []byte - -func BuiltinActorsV8Bundle() []byte { - return actorsv8 -} - -//go:embed builtin-actors/v7/builtin-actors-butterflynet.car -var actorsv7 []byte - -func BuiltinActorsV7Bundle() []byte { - return actorsv7 -} diff --git a/build/builtin_actors_calibnet.go b/build/builtin_actors_calibnet.go deleted file mode 100644 index d73760a77..000000000 --- a/build/builtin_actors_calibnet.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build calibnet -// +build calibnet - -package build - -import ( - _ "embed" -) - -//go:embed builtin-actors/v8/builtin-actors-calibrationnet.car -var actorsv8 []byte - -func BuiltinActorsV8Bundle() []byte { - return actorsv8 -} - -//go:embed builtin-actors/v7/builtin-actors-calibrationnet.car -var actorsv7 []byte - -func BuiltinActorsV7Bundle() []byte { - return actorsv7 -} diff --git a/build/builtin_actors_interop.go b/build/builtin_actors_interop.go deleted file mode 100644 index 8203e4b3d..000000000 --- a/build/builtin_actors_interop.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build interopnet -// +build interopnet - -package build - -import ( - _ "embed" -) - -//go:embed builtin-actors/v8/builtin-actors-caterpillarnet.car -var actorsv8 []byte - -func BuiltinActorsV8Bundle() []byte { - return actorsv8 -} - -//go:embed builtin-actors/v7/builtin-actors-caterpillarnet.car -var actorsv7 []byte - -func BuiltinActorsV7Bundle() []byte { - return actorsv7 -} diff --git a/build/builtin_actors_mainnet.go b/build/builtin_actors_mainnet.go deleted file mode 100644 index 400ac7827..000000000 --- a/build/builtin_actors_mainnet.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build !debug && !2k && !testground && !calibnet && !nerpanet && !butterflynet && !interopnet -// +build !debug,!2k,!testground,!calibnet,!nerpanet,!butterflynet,!interopnet - -package build - -import ( - _ "embed" -) - -//go:embed builtin-actors/v8/builtin-actors-mainnet.car -var actorsv8 []byte - -func BuiltinActorsV8Bundle() []byte { - return actorsv8 -} - -//go:embed builtin-actors/v7/builtin-actors-mainnet.car -var actorsv7 []byte - -func BuiltinActorsV7Bundle() []byte { - return actorsv7 -} diff --git a/chain/actors/bundle.go b/chain/actors/bundle.go new file mode 100644 index 000000000..16a37bd79 --- /dev/null +++ b/chain/actors/bundle.go @@ -0,0 +1,151 @@ +package actors + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "fmt" + "io" + "net/http" + "os" + "path/filepath" + "strings" + + "golang.org/x/xerrors" + + logging "github.com/ipfs/go-log/v2" +) + +var logb = logging.Logger("bundle-fetcher") + +type BundleFetcher struct { + path string +} + +func NewBundleFetcher(basepath string) (*BundleFetcher, error) { + path := filepath.Join(basepath, "builtin-actors") + if err := os.MkdirAll(path, 0755); err != nil { + return nil, xerrors.Errorf("error making bundle directory %s: %w: err") + } + + return &BundleFetcher{path: path}, nil +} + +func (b *BundleFetcher) Fetch(version Version, release, netw string) (path string, err error) { + bundleName := fmt.Sprintf("builtin-actors-%s", netw) + bundleFile := fmt.Sprintf("%s.car", bundleName) + bundleHash := fmt.Sprintf("%s.sha256", bundleName) + bundleBasePath := filepath.Join(b.path, fmt.Sprintf("v%d", version), release) + + if err := os.MkdirAll(bundleBasePath, 0755); err != nil { + return "", xerrors.Errorf("error making bundle directory %s: %w: err") + } + + // check if it exists; if it does, check the hash + bundleFilePath := filepath.Join(bundleBasePath, bundleFile) + if _, err := os.Stat(bundleFilePath); err == nil { + err := b.check(bundleBasePath, bundleFile, bundleHash) + if err == nil { + return bundleFilePath, nil + } + + logb.Warnf("invalid bundle %s: %s; refetching", bundleName, err) + } + + logb.Infof("fetching bundle %s", bundleFile) + if err := b.fetch(release, bundleBasePath, bundleFile, bundleHash); err != nil { + logb.Errorf("error fetching bundle %s: %s", bundleName, err) + return "", xerrors.Errorf("error fetching bundle: %w", err) + } + + if err := b.check(bundleBasePath, bundleFile, bundleHash); err != nil { + logb.Errorf("error checking bundle %s: %s", bundleName, err) + return "", xerrors.Errorf("error checking bundle: %s", err) + } + + return bundleFilePath, nil +} + +func (b *BundleFetcher) fetchURL(url, path string) error { + logb.Infof("fetching URL: %s", url) + + resp, err := http.Get(url) + if err != nil { + return xerrors.Errorf("error fetching %s: %w", url, err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return xerrors.Errorf("error fetching %s: http response status is %d", url, resp.StatusCode) + } + + f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) + if err != nil { + return xerrors.Errorf("error opening %s for writing: %w", path, err) + } + defer f.Close() + + if _, err := io.Copy(f, resp.Body); err != nil { + return xerrors.Errorf("error writing %s: %w", path, err) + } + + return nil +} + +func (b *BundleFetcher) fetch(release, bundleBasePath, bundleFile, bundleHash string) error { + bundleHashUrl := fmt.Sprintf("https://github.com/filecoin-project/builtin-actors/releases/download/%s/%s", + release, bundleHash) + bundleHashPath := filepath.Join(bundleBasePath, bundleHash) + if err := b.fetchURL(bundleHashUrl, bundleHashPath); err != nil { + return err + } + + bundleFileUrl := fmt.Sprintf("https://github.com/filecoin-project/builtin-actors/releases/download/%s/%s", + release, bundleFile) + bundleFilePath := filepath.Join(bundleBasePath, bundleFile) + if err := b.fetchURL(bundleFileUrl, bundleFilePath); err != nil { + return err + } + + return nil +} + +func (b *BundleFetcher) check(bundleBasePath, bundleFile, bundleHash string) error { + bundleHashPath := filepath.Join(bundleBasePath, bundleHash) + f, err := os.Open(bundleHashPath) + if err != nil { + return xerrors.Errorf("error opening %s: %w", bundleHashPath, err) + } + defer f.Close() + + bs, err := io.ReadAll(f) + if err != nil { + return xerrors.Errorf("error reading %s: %w", bundleHashPath, err) + } + + parts := strings.Split(string(bs), " ") + hashHex := parts[0] + expectedDigest, err := hex.DecodeString(hashHex) + if err != nil { + return xerrors.Errorf("error decoding digest from %s: %w", bundleHashPath, err) + } + + bundleFilePath := filepath.Join(bundleBasePath, bundleFile) + f, err = os.Open(bundleFilePath) + if err != nil { + return xerrors.Errorf("error opening %s: %w", bundleFilePath, err) + } + defer f.Close() + + h256 := sha256.New() + if _, err := io.Copy(h256, f); err != nil { + return xerrors.Errorf("error computing digest for %s: %w", bundleFilePath, err) + } + digest := h256.Sum(nil) + + if !bytes.Equal(digest, expectedDigest) { + return xerrors.Errorf("hash mismatch") + } + + return nil +} diff --git a/chain/actors/manifest.go b/chain/actors/manifest.go index 72cc411fa..efc406840 100644 --- a/chain/actors/manifest.go +++ b/chain/actors/manifest.go @@ -3,6 +3,8 @@ package actors import ( "bytes" "context" + "io" + "os" "strings" "sync" @@ -15,6 +17,8 @@ import ( "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/specs-actors/v8/actors/builtin/manifest" + + "github.com/mitchellh/go-homedir" ) var manifestCids map[Version]cid.Cid = map[Version]cid.Cid{ @@ -117,6 +121,40 @@ func CanonicalName(name string) string { return name } +func FetchAndLoadBundle(ctx context.Context, basePath string, bs blockstore.Blockstore, av Version, rel, netw string) (cid.Cid, error) { + fetcher, err := NewBundleFetcher(basePath) + if err != nil { + return cid.Undef, xerrors.Errorf("error creating fetcher for builtin-actors version %d: %w", av, err) + } + + path, err := fetcher.Fetch(av, rel, netw) + if err != nil { + return cid.Undef, xerrors.Errorf("error fetching bundle for builtin-actors version %d: %w", av, err) + } + + f, err := os.Open(path) + if err != nil { + return cid.Undef, xerrors.Errorf("error opening bundle for builtin-actors vresion %d: %w", av, err) + } + defer f.Close() + + data, err := io.ReadAll(f) + if err != nil { + return cid.Undef, xerrors.Errorf("error reading bundle for builtin-actors vresion %d: %w", av, err) + } + + if err := LoadBundle(ctx, bs, av, data); err != nil { + return cid.Undef, xerrors.Errorf("error loading bundle for builtin-actors vresion %d: %w", av, err) + } + + mfCid, ok := GetManifest(av) + if !ok { + return cid.Undef, xerrors.Errorf("missing manifest CID for builtin-actors vrsion %d", av) + } + + return mfCid, nil +} + func LoadBundle(ctx context.Context, bs blockstore.Blockstore, av Version, data []byte) error { blobr := bytes.NewReader(data) @@ -131,11 +169,34 @@ func LoadBundle(ctx context.Context, bs blockstore.Blockstore, av Version, data return nil } -func LoadManifestFromBundle(ctx context.Context, bs blockstore.Blockstore, av Version, data []byte) error { - if err := LoadBundle(ctx, bs, av, data); err != nil { +// utility for blanket loading outside DI +func FetchAndLoadBundles(ctx context.Context, bs blockstore.Blockstore, bar map[Version]string) error { + // TODO: how to get the network name properly? + netw := "mainnet" + if v := os.Getenv("LOTUS_FIL_NETWORK"); v != "" { + netw = v + } + + // TODO: how to get the repo properly? + path, err := homedir.Expand("~/.lotus") + if err != nil { return err } + if p := os.Getenv("LOTUS_PATH"); p != "" { + path = p + } + + for av, rel := range bar { + if _, err := FetchAndLoadBundle(ctx, path, bs, av, rel, netw); err != nil { + return err + } + } + cborStore := cbor.NewCborStore(bs) - return LoadManifests(ctx, cborStore) + if err := LoadManifests(ctx, cborStore); err != nil { + return err + } + + return nil } diff --git a/cli/init.go b/cli/init.go deleted file mode 100644 index f90811556..000000000 --- a/cli/init.go +++ /dev/null @@ -1,22 +0,0 @@ -package cli - -import ( - "context" - "fmt" - - "github.com/filecoin-project/lotus/blockstore" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/actors" -) - -func init() { - // preload manifest so that we have the correct code CID inventory for cli since that doesn't - // go through CI - if len(build.BuiltinActorsV8Bundle()) > 0 { - bs := blockstore.NewMemory() - - if err := actors.LoadManifestFromBundle(context.TODO(), bs, actors.Version8, build.BuiltinActorsV8Bundle()); err != nil { - panic(fmt.Errorf("error loading actor manifest: %w", err)) - } - } -} diff --git a/cli/util/api.go b/cli/util/api.go index 6c673d91f..65afaf955 100644 --- a/cli/util/api.go +++ b/cli/util/api.go @@ -21,6 +21,9 @@ import ( "github.com/filecoin-project/lotus/api/client" "github.com/filecoin-project/lotus/api/v0api" "github.com/filecoin-project/lotus/api/v1api" + "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/node/repo" ) @@ -28,6 +31,14 @@ const ( metadataTraceContext = "traceContext" ) +func loadBundles(ctx context.Context) error { + // preload manifest so that we have the correct code CID inventory for cli since that doesn't + // go through CI + bs := blockstore.NewMemory() + + return actors.FetchAndLoadBundles(ctx, bs, build.BuiltinActorReleases) +} + // GetAPIInfo returns the API endpoint to use for the specified kind of repo. // // The order of precedence is as follows: @@ -37,6 +48,11 @@ const ( // 3. deprecated *_API_INFO environment variables // 4. *-repo command line flags. func GetAPIInfo(ctx *cli.Context, t repo.RepoType) (APIInfo, error) { + // do this first + if err := loadBundles(ctx.Context); err != nil { + return APIInfo{}, fmt.Errorf("error loading builtin-actor bundles: %w", err) + } + // Check if there was a flag passed with the listen address of the API // server (only used by the tests) for _, f := range t.APIFlags() { diff --git a/cmd/lotus-miner/init.go b/cmd/lotus-miner/init.go index abda9df26..144fb63ce 100644 --- a/cmd/lotus-miner/init.go +++ b/cmd/lotus-miner/init.go @@ -216,12 +216,11 @@ var initCmd = &cli.Command{ return err } - if len(build.BuiltinActorsV8Bundle()) > 0 { - bs := blockstore.NewMemory() + // load bundles + bs := blockstore.NewMemory() - if err := actors.LoadManifestFromBundle(context.TODO(), bs, actors.Version8, build.BuiltinActorsV8Bundle()); err != nil { - return xerrors.Errorf("error loading actor manifest: %w", err) - } + if err := actors.FetchAndLoadBundles(ctx, bs, build.BuiltinActorReleases); err != nil { + return err } var localPaths []stores.LocalPath diff --git a/cmd/lotus-seed/genesis.go b/cmd/lotus-seed/genesis.go index 34dd15b89..6ae501687 100644 --- a/cmd/lotus-seed/genesis.go +++ b/cmd/lotus-seed/genesis.go @@ -1,7 +1,6 @@ package main import ( - "context" "encoding/csv" "encoding/json" "fmt" @@ -580,11 +579,12 @@ var genesisCarCmd = &cli.Command{ jrnl := journal.NilJournal() bstor := blockstore.WrapIDStore(blockstore.NewMemorySync()) sbldr := vm.Syscalls(ffiwrapper.ProofVerifier) - if len(build.BuiltinActorsV8Bundle()) > 0 { - if err := actors.LoadManifestFromBundle(context.TODO(), bstor, actors.Version8, build.BuiltinActorsV8Bundle()); err != nil { - return xerrors.Errorf("error loading actor manifest: %w", err) - } + + // load appropriate bundles + if err := actors.FetchAndLoadBundles(c.Context, bstor, build.BuiltinActorReleases); err != nil { + return err } + _, err := testing.MakeGenesis(ofile, c.Args().First())(bstor, sbldr, jrnl, dtypes.BuiltinActorsLoaded{})() return err }, diff --git a/node/modules/builtin_actors.go b/node/modules/builtin_actors.go index b5d7b9ce9..3cfb41257 100644 --- a/node/modules/builtin_actors.go +++ b/node/modules/builtin_actors.go @@ -2,8 +2,8 @@ package modules import ( "fmt" - "io" "os" + "sync" "go.uber.org/fx" "golang.org/x/xerrors" @@ -12,28 +12,60 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/helpers" + "github.com/filecoin-project/lotus/node/repo" + cid "github.com/ipfs/go-cid" + dstore "github.com/ipfs/go-datastore" cbor "github.com/ipfs/go-ipld-cbor" ) -func LoadBultinActors(lc fx.Lifecycle, mctx helpers.MetricsCtx, bs dtypes.UniversalBlockstore) (result dtypes.BuiltinActorsLoaded, err error) { +func LoadBultinActors(lc fx.Lifecycle, mctx helpers.MetricsCtx, r repo.LockedRepo, bs dtypes.UniversalBlockstore, ds dtypes.MetadataDS) (result dtypes.BuiltinActorsLoaded, err error) { ctx := helpers.LifecycleCtx(mctx, lc) - // TODO eventually we want this to start with bundle/manifest CIDs and fetch them from IPFS if - // not already loaded. - // For now, we just embed the v8 bundle and adjust the manifest CIDs for the migration/actor - // metadata. - if len(build.BuiltinActorsV8Bundle()) > 0 { - if err := actors.LoadBundle(ctx, bs, actors.Version8, build.BuiltinActorsV8Bundle()); err != nil { - return result, err - } + // TODO how to properly get the network name? + // putting it as a dep in inputs causes a stack overflow in DI from circular dependency + // sigh... + netw := "mainnet" + if v := os.Getenv("LOTUS_FIL_NETWORK"); v != "" { + netw = v } - // for testing -- need to also set LOTUS_USE_FVM_CUSTOM_BUNDLE=1 to force the fvm to use it. - if len(build.BuiltinActorsV7Bundle()) > 0 { - if err := actors.LoadBundle(ctx, bs, actors.Version7, build.BuiltinActorsV7Bundle()); err != nil { + for av, rel := range build.BuiltinActorReleases { + key := dstore.NewKey(fmt.Sprintf("/builtin-actors/v%d/%s", av, rel)) + + data, err := ds.Get(ctx, key) + switch err { + case nil: + mfCid, err := cid.Cast(data) + if err != nil { + return result, xerrors.Errorf("error parsing cid for %s: %w", key, err) + } + + has, err := bs.Has(ctx, mfCid) + if err != nil { + return result, xerrors.Errorf("error checking blockstore for manifest cid %s: %w", mfCid, err) + } + + if has { + actors.AddManifest(av, mfCid) + continue + } + + case dstore.ErrNotFound: + + default: + return result, xerrors.Errorf("error loading %s from datastore: %w", key, err) + } + + // ok, we don't have it -- fetch it and add it to the blockstore + mfCid, err := actors.FetchAndLoadBundle(ctx, r.Path(), bs, av, rel, string(netw)) + if err != nil { return result, err } + + if err := ds.Put(ctx, key, mfCid.Bytes()); err != nil { + return result, xerrors.Errorf("error storing manifest CID for builtin-actors vrsion %d to the datastore: %w", av, err) + } } cborStore := cbor.NewCborStore(bs) @@ -45,38 +77,26 @@ func LoadBultinActors(lc fx.Lifecycle, mctx helpers.MetricsCtx, bs dtypes.Univer } // for itests +var testingBundleMx sync.Mutex + func LoadBuiltinActorsTesting(lc fx.Lifecycle, mctx helpers.MetricsCtx, bs dtypes.UniversalBlockstore) (result dtypes.BuiltinActorsLoaded, err error) { ctx := helpers.LifecycleCtx(mctx, lc) - base := os.Getenv("LOTUS_SRC_DIR") - if base == "" { - base = "." - } - - var template string + var netw string if build.InsecurePoStValidation { - template = "%s/build/builtin-actors/v%d/builtin-actors-testing-fake-proofs.car" + netw = "testing-fake-proofs" } else { - template = "%s/build/builtin-actors/v%d/builtin-actors-testing.car" + netw = "testing" } - for _, ver := range []actors.Version{actors.Version8} { - path := fmt.Sprintf(template, base, ver) + testingBundleMx.Lock() + defer testingBundleMx.Unlock() - log.Infof("loading testing bundle: %s", path) + for av, rel := range build.BuiltinActorReleases { + const basePath = "/tmp/lotus-testing" - file, err := os.Open(path) - if err != nil { - return result, xerrors.Errorf("error opening v%d bundle: %w", ver, err) - } - - bundle, err := io.ReadAll(file) - if err != nil { - return result, xerrors.Errorf("error reading v%d bundle: %w", ver, err) - } - - if err := actors.LoadBundle(ctx, bs, actors.Version8, bundle); err != nil { - return result, xerrors.Errorf("error loading v%d bundle: %w", ver, err) + if _, err := actors.FetchAndLoadBundle(ctx, basePath, bs, av, rel, netw); err != nil { + return result, xerrors.Errorf("error loading bundle for builtin-actors vresion %d: %w", av, err) } }