Skip to content

Commit a133190

Browse files
authored
feat: add simple migration nv27 (#386)
* feat: add simple migration nv27 * Run gofmt
1 parent 65aa7de commit a133190

File tree

2 files changed

+144
-0
lines changed

2 files changed

+144
-0
lines changed

builtin/v17/migration/system.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package migration
2+
3+
import (
4+
"context"
5+
6+
system14 "github.com/filecoin-project/go-state-types/builtin/v14/system"
7+
8+
"github.com/filecoin-project/go-state-types/migration"
9+
10+
"github.com/ipfs/go-cid"
11+
cbor "github.com/ipfs/go-ipld-cbor"
12+
)
13+
14+
// System Actor migrator
15+
type systemActorMigrator struct {
16+
OutCodeCID cid.Cid
17+
ManifestData cid.Cid
18+
}
19+
20+
func (m systemActorMigrator) MigratedCodeCID() cid.Cid {
21+
return m.OutCodeCID
22+
}
23+
24+
func (m systemActorMigrator) MigrateState(ctx context.Context, store cbor.IpldStore, in migration.ActorMigrationInput) (*migration.ActorMigrationResult, error) {
25+
// The ManifestData itself is already in the blockstore
26+
state := system14.State{BuiltinActors: m.ManifestData}
27+
stateHead, err := store.Put(ctx, &state)
28+
if err != nil {
29+
return nil, err
30+
}
31+
32+
return &migration.ActorMigrationResult{
33+
NewCodeCID: m.OutCodeCID,
34+
NewHead: stateHead,
35+
}, nil
36+
}
37+
38+
func (m systemActorMigrator) Deferred() bool {
39+
return false
40+
}

builtin/v17/migration/top.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package migration
2+
3+
import (
4+
"context"
5+
6+
adt14 "github.com/filecoin-project/go-state-types/builtin/v14/util/adt"
7+
8+
system13 "github.com/filecoin-project/go-state-types/builtin/v13/system"
9+
10+
"github.com/filecoin-project/go-state-types/abi"
11+
"github.com/filecoin-project/go-state-types/builtin"
12+
"github.com/filecoin-project/go-state-types/manifest"
13+
"github.com/filecoin-project/go-state-types/migration"
14+
15+
"github.com/ipfs/go-cid"
16+
cbor "github.com/ipfs/go-ipld-cbor"
17+
"golang.org/x/xerrors"
18+
)
19+
20+
// MigrateStateTree Migrates the filecoin state tree starting from the global state tree and upgrading all actor state.
21+
// The store must support concurrent writes (even if the configured worker count is 1).
22+
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) {
23+
if cfg.MaxWorkers <= 0 {
24+
return cid.Undef, xerrors.Errorf("invalid migration config with %d workers", cfg.MaxWorkers)
25+
}
26+
27+
adtStore := adt14.WrapStore(ctx, store)
28+
29+
// Load input and output state trees
30+
actorsIn, err := builtin.LoadTree(adtStore, actorsRootIn)
31+
if err != nil {
32+
return cid.Undef, xerrors.Errorf("loading state tree: %w", err)
33+
}
34+
35+
// load old manifest data
36+
systemActor, ok, err := actorsIn.GetActorV5(builtin.SystemActorAddr)
37+
if err != nil {
38+
return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err)
39+
}
40+
41+
if !ok {
42+
return cid.Undef, xerrors.New("didn't find system actor")
43+
}
44+
45+
var systemState system13.State
46+
if err := store.Get(ctx, systemActor.Head, &systemState); err != nil {
47+
return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err)
48+
}
49+
50+
var oldManifestData manifest.ManifestData
51+
if err := store.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil {
52+
return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err)
53+
}
54+
55+
// load new manifest
56+
var newManifest manifest.Manifest
57+
if err := adtStore.Get(ctx, newManifestCID, &newManifest); err != nil {
58+
return cid.Undef, xerrors.Errorf("error reading actor manifest: %w", err)
59+
}
60+
61+
if err := newManifest.Load(ctx, adtStore); err != nil {
62+
return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err)
63+
}
64+
65+
// Maps prior version code CIDs to migration functions.
66+
migrations := make(map[cid.Cid]migration.ActorMigration)
67+
// Set of prior version code CIDs for actors to defer during iteration, for explicit migration afterwards.
68+
deferredCodeIDs := make(map[cid.Cid]struct{})
69+
70+
for _, oldEntry := range oldManifestData.Entries {
71+
newCodeCID, ok := newManifest.Get(oldEntry.Name)
72+
if !ok {
73+
return cid.Undef, xerrors.Errorf("code cid for %s actor not found in new manifest", oldEntry.Name)
74+
}
75+
migrations[oldEntry.Code] = migration.CachedMigration(cache, migration.CodeMigrator{OutCodeCID: newCodeCID})
76+
}
77+
78+
// migrations that migrate both code and state, override entries in `migrations`
79+
80+
// The System Actor
81+
82+
newSystemCodeCID, ok := newManifest.Get(manifest.SystemKey)
83+
if !ok {
84+
return cid.Undef, xerrors.Errorf("code cid for system actor not found in new manifest")
85+
}
86+
87+
migrations[systemActor.Code] = systemActorMigrator{OutCodeCID: newSystemCodeCID, ManifestData: newManifest.Data}
88+
89+
if len(migrations)+len(deferredCodeIDs) != len(oldManifestData.Entries) {
90+
return cid.Undef, xerrors.Errorf("incomplete migration specification with %d code CIDs, need %d", len(migrations)+len(deferredCodeIDs), len(oldManifestData.Entries))
91+
}
92+
93+
actorsOut, err := migration.RunMigration(ctx, cfg, cache, store, log, actorsIn, migrations)
94+
if err != nil {
95+
return cid.Undef, xerrors.Errorf("failed to run migration: %w", err)
96+
}
97+
98+
outCid, err := actorsOut.Flush()
99+
if err != nil {
100+
return cid.Undef, xerrors.Errorf("failed to flush actorsOut: %w", err)
101+
}
102+
103+
return outCid, nil
104+
}

0 commit comments

Comments
 (0)