-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add simple migration nv25 (#325)
* chore: create base nv25 skeleton chore: create base nv25 skeleton * chore: delete migration specific for nv24 chore: delete migration specific for nv24 * chore: add simple migration nv25 chore: add simple migration nv25
- Loading branch information
Showing
2 changed files
with
144 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package migration | ||
|
||
import ( | ||
"context" | ||
|
||
system16 "github.com/filecoin-project/go-state-types/builtin/v16/system" | ||
|
||
"github.com/filecoin-project/go-state-types/migration" | ||
|
||
"github.com/ipfs/go-cid" | ||
cbor "github.com/ipfs/go-ipld-cbor" | ||
) | ||
|
||
// System Actor migrator | ||
type systemActorMigrator struct { | ||
OutCodeCID cid.Cid | ||
ManifestData cid.Cid | ||
} | ||
|
||
func (m systemActorMigrator) MigratedCodeCID() cid.Cid { | ||
return m.OutCodeCID | ||
} | ||
|
||
func (m systemActorMigrator) MigrateState(ctx context.Context, store cbor.IpldStore, in migration.ActorMigrationInput) (*migration.ActorMigrationResult, error) { | ||
// The ManifestData itself is already in the blockstore | ||
state := system16.State{BuiltinActors: m.ManifestData} | ||
stateHead, err := store.Put(ctx, &state) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &migration.ActorMigrationResult{ | ||
NewCodeCID: m.OutCodeCID, | ||
NewHead: stateHead, | ||
}, nil | ||
} | ||
|
||
func (m systemActorMigrator) Deferred() bool { | ||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package migration | ||
|
||
import ( | ||
"context" | ||
|
||
adt16 "github.com/filecoin-project/go-state-types/builtin/v16/util/adt" | ||
|
||
system15 "github.com/filecoin-project/go-state-types/builtin/v13/system" | ||
|
||
"github.com/filecoin-project/go-state-types/abi" | ||
"github.com/filecoin-project/go-state-types/builtin" | ||
"github.com/filecoin-project/go-state-types/manifest" | ||
"github.com/filecoin-project/go-state-types/migration" | ||
|
||
"github.com/ipfs/go-cid" | ||
cbor "github.com/ipfs/go-ipld-cbor" | ||
"golang.org/x/xerrors" | ||
) | ||
|
||
// MigrateStateTree Migrates the filecoin state tree starting from the global state tree and upgrading all actor state. | ||
// The store must support concurrent writes (even if the configured worker count is 1). | ||
func MigrateStateTree(ctx context.Context, store cbor.IpldStore, newManifestCID cid.Cid, actorsRootIn cid.Cid, priorEpoch abi.ChainEpoch, cfg migration.Config, log migration.Logger, cache migration.MigrationCache) (cid.Cid, error) { | ||
if cfg.MaxWorkers <= 0 { | ||
return cid.Undef, xerrors.Errorf("invalid migration config with %d workers", cfg.MaxWorkers) | ||
} | ||
|
||
adtStore := adt16.WrapStore(ctx, store) | ||
|
||
// Load input and output state trees | ||
actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn) | ||
if err != nil { | ||
return cid.Undef, xerrors.Errorf("loading state tree: %w", err) | ||
} | ||
|
||
// load old manifest data | ||
systemActor, ok, err := actorsIn.GetActorV5(builtin.SystemActorAddr) | ||
if err != nil { | ||
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err) | ||
} | ||
|
||
if !ok { | ||
return cid.Undef, xerrors.New("didn't find system actor") | ||
} | ||
|
||
var systemState system15.State | ||
if err := store.Get(ctx, systemActor.Head, &systemState); err != nil { | ||
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err) | ||
} | ||
|
||
var oldManifestData manifest.ManifestData | ||
if err := store.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil { | ||
return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err) | ||
} | ||
|
||
// load new manifest | ||
var newManifest manifest.Manifest | ||
if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil { | ||
return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err) | ||
} | ||
|
||
if err := newManifest.Load(ctx, adtStore); err != nil { | ||
return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err) | ||
} | ||
|
||
// Maps prior version code CIDs to migration functions. | ||
migrations := make(map[cid.Cid]migration.ActorMigration) | ||
// Set of prior version code CIDs for actors to defer during iteration, for explicit migration afterwards. | ||
deferredCodeIDs := make(map[cid.Cid]struct{}) | ||
|
||
for _, oldEntry := range oldManifestData.Entries { | ||
newCodeCID, ok := newManifest.Get(oldEntry.Name) | ||
if !ok { | ||
return cid.Undef, xerrors.Errorf("code cid for %s actor not found in new manifest", oldEntry.Name) | ||
} | ||
migrations[oldEntry.Code] = migration.CachedMigration(cache, migration.CodeMigrator{OutCodeCID: newCodeCID}) | ||
} | ||
|
||
// migrations that migrate both code and state, override entries in `migrations` | ||
|
||
// The System Actor | ||
|
||
newSystemCodeCID, ok := newManifest.Get(manifest.SystemKey) | ||
if !ok { | ||
return cid.Undef, xerrors.Errorf("code cid for system actor not found in new manifest") | ||
} | ||
|
||
migrations[systemActor.Code] = systemActorMigrator{OutCodeCID: newSystemCodeCID, ManifestData: newManifest.Data} | ||
|
||
if len(migrations)+len(deferredCodeIDs) != len(oldManifestData.Entries) { | ||
return cid.Undef, xerrors.Errorf("incomplete migration specification with %d code CIDs, need %d", len(migrations)+len(deferredCodeIDs), len(oldManifestData.Entries)) | ||
} | ||
|
||
actorsOut, err := migration.RunMigration(ctx, cfg, cache, store, log, actorsIn, migrations) | ||
if err != nil { | ||
return cid.Undef, xerrors.Errorf("failed to run migration: %w", err) | ||
} | ||
|
||
outCid, err := actorsOut.Flush() | ||
if err != nil { | ||
return cid.Undef, xerrors.Errorf("failed to flush actorsOut: %w", err) | ||
} | ||
|
||
return outCid, nil | ||
} |