diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go index 91b4bc98ba5..5b683bc70bc 100644 --- a/chain/consensus/filcns/upgrades.go +++ b/chain/consensus/filcns/upgrades.go @@ -279,8 +279,13 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { }, { Height: build.UpgradeWatermelonFixHeight, Network: network.Version21, - Migration: upgradeActorsV12Fix, + Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID, calibnetv12BuggyManifest2CID), }, + { + Height: build.UpgradeWatermelonFix2Height, + Network: network.Version21, + Migration: buildUpgradeActorsV12MinerFix(calibnetv12BuggyMinerCID2, calibnetv12CorrectManifestCID1), + }, } for _, u := range updates { @@ -293,6 +298,14 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { return us } +var ( + calibnetv12BuggyMinerCID = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq") + calibnetv12BuggyMinerCID2 = cid.MustParse("bafk2bzaced7emkbbnrewv5uvrokxpf5tlm4jslu2jsv77ofw2yqdglg657uie") + + calibnetv12BuggyManifest2CID = cid.MustParse("bafy2bzacebl4w5ptfvuw6746w7ev562idkbf5ppq72e6zub22435ws2rukzru") + calibnetv12CorrectManifestCID1 = cid.MustParse("") +) + func UpgradeFaucetBurnRecovery(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, em stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { // Some initial parameters FundsForMiners := types.FromFil(1_000_000) @@ -1974,148 +1987,141 @@ func upgradeActorsV12Common( return newRoot, nil } -////////////////////// +// //////////////////// +func buildUpgradeActorsV12MinerFix(minerCid, newManifestCID cid.Cid) func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + return func(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { + stateStore := sm.ChainStore().StateBlockstore() + adtStore := store.ActorStore(ctx, stateStore) -var calibnetv12BuggyMinerCID = cid.MustParse("bafk2bzacecnh2ouohmonvebq7uughh4h3ppmg4cjsk74dzxlbbtlcij4xbzxq") + // ensure that the manifest is loaded in the blockstore + if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil { + return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err) + } -func upgradeActorsV12Fix(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor, - root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) { - stateStore := sm.ChainStore().StateBlockstore() - adtStore := store.ActorStore(ctx, stateStore) + // Load input state tree + actorsIn, err := state.LoadStateTree(adtStore, root) + if err != nil { + return cid.Undef, xerrors.Errorf("loading state tree: %w", err) + } - // ensure that the manifest is loaded in the blockstore - if err := bundle.LoadBundles(ctx, stateStore, actorstypes.Version12); err != nil { - return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err) - } + // load old manifest data + systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err) + } - // Load input state tree - actorsIn, err := state.LoadStateTree(adtStore, root) - if err != nil { - return cid.Undef, xerrors.Errorf("loading state tree: %w", err) - } + var systemState system11.State + if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil { + return cid.Undef, xerrors.Errorf("failed to get system actor state: %w", err) + } - // load old manifest data - systemActor, err := actorsIn.GetActor(builtin.SystemActorAddr) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to get system actor: %w", err) - } + var oldManifestData manifest.ManifestData + if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil { + return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err) + } - var systemState system11.State - if err := adtStore.Get(ctx, systemActor.Head, &systemState); err != nil { - return cid.Undef, xerrors.Errorf("failed to get system actor state: %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) + } - var oldManifestData manifest.ManifestData - if err := adtStore.Get(ctx, systemState.BuiltinActors, &oldManifestData); err != nil { - return cid.Undef, xerrors.Errorf("failed to get old manifest data: %w", err) - } + if err := newManifest.Load(ctx, adtStore); err != nil { + return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err) + } - newManifestCID, ok := actors.GetManifest(actorstypes.Version12) - if !ok { - return cid.Undef, xerrors.Errorf("no manifest CID for v12 upgrade") - } + // build the CID mapping + codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries)) + for _, oldEntry := range oldManifestData.Entries { + newCID, ok := newManifest.Get(oldEntry.Name) + if !ok { + return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name) + } - // 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) - } + // Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor + codeMapping[oldEntry.Code] = newCID + } - if err := newManifest.Load(ctx, adtStore); err != nil { - return cid.Undef, xerrors.Errorf("error loading actor manifest: %w", err) - } + // Create empty actorsOut - // build the CID mapping - codeMapping := make(map[cid.Cid]cid.Cid, len(oldManifestData.Entries)) - for _, oldEntry := range oldManifestData.Entries { - newCID, ok := newManifest.Get(oldEntry.Name) - if !ok { - return cid.Undef, xerrors.Errorf("missing manifest entry for %s", oldEntry.Name) + actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version()) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err) } - // Note: we expect newCID to be the same as oldEntry.Code for all actors except the miner actor - codeMapping[oldEntry.Code] = newCID - } - - // Create empty actorsOut + // Perform the migration + err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error { + newCid, ok := codeMapping[actor.Code] + if !ok { + return xerrors.Errorf("didn't find mapping for %s", actor.Code) + } - actorsOut, err := state.NewStateTree(adtStore, actorsIn.Version()) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to create new tree: %w", err) - } + return actorsOut.SetActor(a, &types.ActorV5{ + Code: newCid, + Head: actor.Head, + Nonce: actor.Nonce, + Balance: actor.Balance, + Address: actor.Address, + }) + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err) + } - // Perform the migration - err = actorsIn.ForEach(func(a address.Address, actor *types.Actor) error { - newCid, ok := codeMapping[actor.Code] - if !ok { - return xerrors.Errorf("didn't find mapping for %s", actor.Code) + systemState.BuiltinActors = newManifest.Data + newSystemHead, err := adtStore.Put(ctx, &systemState) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err) } - return actorsOut.SetActor(a, &types.ActorV5{ - Code: newCid, - Head: actor.Head, - Nonce: actor.Nonce, - Balance: actor.Balance, - Address: actor.Address, - }) - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to perform migration: %w", err) - } + systemActor.Head = newSystemHead + if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil { + return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err) + } - systemState.BuiltinActors = newManifest.Data - newSystemHead, err := adtStore.Put(ctx, &systemState) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to put new system state: %w", err) - } + // Sanity checking - systemActor.Head = newSystemHead - if err = actorsOut.SetActor(builtin.SystemActorAddr, systemActor); err != nil { - return cid.Undef, xerrors.Errorf("failed to put new system actor: %w", err) - } + err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error { + outActor, err := actorsOut.GetActor(a) + if err != nil { + return xerrors.Errorf("failed to get actor in outTree: %w", err) + } - // Sanity checking + if inActor.Nonce != outActor.Nonce { + return xerrors.Errorf("mismatched nonce for actor %s", a) + } - err = actorsIn.ForEach(func(a address.Address, inActor *types.Actor) error { - outActor, err := actorsOut.GetActor(a) - if err != nil { - return xerrors.Errorf("failed to get actor in outTree: %w", err) - } + if !inActor.Balance.Equals(outActor.Balance) { + return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance) + } - if inActor.Nonce != outActor.Nonce { - return xerrors.Errorf("mismatched nonce for actor %s", a) - } + if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() { + return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address) + } - if !inActor.Balance.Equals(outActor.Balance) { - return xerrors.Errorf("mismatched balance for actor %s: %d != %d", a, inActor.Balance, outActor.Balance) - } + if inActor.Head != outActor.Head && a != builtin.SystemActorAddr { + return xerrors.Errorf("mismatched head for actor %s", a) + } - if inActor.Address != outActor.Address && inActor.Address.String() != outActor.Address.String() { - return xerrors.Errorf("mismatched address for actor %s: %s != %s", a, inActor.Address, outActor.Address) - } + // This is the hard-coded "buggy" miner actor Code ID + if inActor.Code != minerCid && inActor.Code != outActor.Code { + return xerrors.Errorf("unexpected change in code for actor %s", a) + } - if inActor.Head != outActor.Head && a != builtin.SystemActorAddr { - return xerrors.Errorf("mismatched head for actor %s", a) + return nil + }) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err) } - // This is the hard-coded "buggy" miner actor Code ID - if inActor.Code != calibnetv12BuggyMinerCID && inActor.Code != outActor.Code { - return xerrors.Errorf("unexpected change in code for actor %s", a) + // Persist the result. + newRoot, err := actorsOut.Flush(ctx) + if err != nil { + return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) } - return nil - }) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to sanity check migration: %w", err) - } - - // Persist the result. - newRoot, err := actorsOut.Flush(ctx) - if err != nil { - return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err) + return newRoot, nil } - - return newRoot, nil } ////////////////////