Merge pull request #9525 from filecoin-project/asr/premigrations
feat: state: add a second premigration for nv17
This commit is contained in:
commit
26ba489746
@ -197,8 +197,13 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
|
||||
Migration: UpgradeActorsV9,
|
||||
PreMigrations: []stmgr.PreMigration{{
|
||||
PreMigration: PreUpgradeActorsV9,
|
||||
StartWithin: 180,
|
||||
StartWithin: 240,
|
||||
DontStartWithin: 60,
|
||||
StopWithin: 20,
|
||||
}, {
|
||||
PreMigration: PreUpgradeActorsV9,
|
||||
StartWithin: 15,
|
||||
DontStartWithin: 10,
|
||||
StopWithin: 5,
|
||||
}},
|
||||
Expensive: true,
|
||||
|
@ -1,20 +1,177 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/filecoin-project/go-state-types/abi"
|
||||
miner9 "github.com/filecoin-project/go-state-types/builtin/v9/miner"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/store"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
"github.com/filecoin-project/lotus/node/repo"
|
||||
)
|
||||
|
||||
var diffCmd = &cli.Command{
|
||||
Name: "diff",
|
||||
Usage: "diff state objects",
|
||||
Subcommands: []*cli.Command{diffStateTrees},
|
||||
Name: "diff",
|
||||
Usage: "diff state objects",
|
||||
Subcommands: []*cli.Command{
|
||||
diffStateTrees,
|
||||
diffMinerStates,
|
||||
},
|
||||
}
|
||||
|
||||
var diffMinerStates = &cli.Command{
|
||||
Name: "miner-states",
|
||||
Usage: "diff two miner-states",
|
||||
ArgsUsage: "<stateCidA> <stateCidB>",
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
ctx := context.TODO()
|
||||
|
||||
if cctx.NArg() != 2 {
|
||||
return lcli.IncorrectNumArgs(cctx)
|
||||
}
|
||||
|
||||
stCidA, err := cid.Decode(cctx.Args().First())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse input: %w", err)
|
||||
}
|
||||
|
||||
stCidB, err := cid.Decode(cctx.Args().Get(1))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse input: %w", err)
|
||||
}
|
||||
|
||||
fsrepo, err := repo.NewFS(cctx.String("repo"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
lkrepo, err := fsrepo.Lock(repo.FullNode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer lkrepo.Close() //nolint:errcheck
|
||||
|
||||
bs, err := lkrepo.Blockstore(ctx, repo.UniversalBlockstore)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open blockstore: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
if c, ok := bs.(io.Closer); ok {
|
||||
if err := c.Close(); err != nil {
|
||||
log.Warnf("failed to close blockstore: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
actorStore := store.ActorStore(ctx, bs)
|
||||
|
||||
var minerStA miner9.State
|
||||
if err = actorStore.Get(ctx, stCidA, &minerStA); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var minerStB miner9.State
|
||||
if err = actorStore.Get(ctx, stCidB, &minerStB); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println(minerStA.Deadlines)
|
||||
fmt.Println(minerStB.Deadlines)
|
||||
|
||||
minerDeadlinesA, err := minerStA.LoadDeadlines(actorStore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minerDeadlinesB, err := minerStB.LoadDeadlines(actorStore)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, dACid := range minerDeadlinesA.Due {
|
||||
dBCid := minerDeadlinesB.Due[i]
|
||||
if dACid != dBCid {
|
||||
fmt.Println("Difference at index ", i, dACid, " != ", dBCid)
|
||||
dA, err := minerDeadlinesA.LoadDeadline(actorStore, uint64(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dB, err := minerDeadlinesB.LoadDeadline(actorStore, uint64(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if dA.SectorsSnapshot != dB.SectorsSnapshot {
|
||||
fmt.Println("They differ at Sectors snapshot ", dA.SectorsSnapshot, " != ", dB.SectorsSnapshot)
|
||||
|
||||
sectorsSnapshotA, err := miner9.LoadSectors(actorStore, dA.SectorsSnapshot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sectorsSnapshotB, err := miner9.LoadSectors(actorStore, dB.SectorsSnapshot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if sectorsSnapshotA.Length() != sectorsSnapshotB.Length() {
|
||||
fmt.Println("sector snapshots have different lengts!")
|
||||
}
|
||||
|
||||
var infoA miner9.SectorOnChainInfo
|
||||
err = sectorsSnapshotA.ForEach(&infoA, func(i int64) error {
|
||||
infoB, ok, err := sectorsSnapshotB.Get(abi.SectorNumber(i))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
fmt.Println(i, "isn't found in infoB!!")
|
||||
}
|
||||
|
||||
if !infoA.DealWeight.Equals(infoB.DealWeight) {
|
||||
fmt.Println("Deal Weights differ! ", infoA.DealWeight, infoB.DealWeight)
|
||||
}
|
||||
|
||||
if !infoA.VerifiedDealWeight.Equals(infoB.VerifiedDealWeight) {
|
||||
fmt.Println("Verified Deal Weights differ! ", infoA.VerifiedDealWeight, infoB.VerifiedDealWeight)
|
||||
}
|
||||
|
||||
infoStrA := fmt.Sprint(infoA)
|
||||
infoStrB := fmt.Sprint(*infoB)
|
||||
if infoStrA != infoStrB {
|
||||
fmt.Println(infoStrA)
|
||||
fmt.Println(infoStrB)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var diffStateTrees = &cli.Command{
|
||||
|
@ -52,6 +52,9 @@ var migrationsCmd = &cli.Command{
|
||||
Name: "repo",
|
||||
Value: "~/.lotus",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "check-invariants",
|
||||
},
|
||||
},
|
||||
Action: func(cctx *cli.Context) error {
|
||||
ctx := context.TODO()
|
||||
@ -115,7 +118,7 @@ var migrationsCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-180, migrationTs, false)
|
||||
ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -127,41 +130,65 @@ var migrationsCmd = &cli.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("completed round 1, took ", time.Since(startTime))
|
||||
preMigration1Time := time.Since(startTime)
|
||||
|
||||
ts2, err := cs.GetTipsetByHeight(ctx, blk.Height-15, migrationTs, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
startTime = time.Now()
|
||||
|
||||
err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
preMigration2Time := time.Since(startTime)
|
||||
|
||||
startTime = time.Now()
|
||||
|
||||
newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("completed round actual (with cache), took ", time.Since(startTime))
|
||||
|
||||
fmt.Println("new cid", newCid1)
|
||||
cachedMigrationTime := time.Since(startTime)
|
||||
|
||||
startTime = time.Now()
|
||||
|
||||
newCid2, err := filcns.UpgradeActorsV9(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("completed round actual (without cache), took ", time.Since(startTime))
|
||||
|
||||
fmt.Println("new cid", newCid2)
|
||||
uncachedMigrationTime := time.Since(startTime)
|
||||
|
||||
if newCid1 != newCid2 {
|
||||
return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1,
|
||||
newCid2)
|
||||
}
|
||||
|
||||
err = checkStateInvariants(ctx, blk.ParentStateRoot, newCid1, bs)
|
||||
if err != nil {
|
||||
return err
|
||||
fmt.Println("new cid", newCid2)
|
||||
fmt.Println("completed premigration 1, took ", preMigration1Time)
|
||||
fmt.Println("completed premigration 2, took ", preMigration2Time)
|
||||
fmt.Println("completed round actual (with cache), took ", cachedMigrationTime)
|
||||
fmt.Println("completed round actual (without cache), took ", uncachedMigrationTime)
|
||||
|
||||
if cctx.Bool("check-invariants") {
|
||||
err = checkMigrationInvariants(ctx, blk.ParentStateRoot, newCid1, bs, blk.Height-1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot cid.Cid, bs blockstore.Blockstore) error {
|
||||
actorStore := store.ActorStore(ctx, blockstore.NewTieredBstore(bs, blockstore.NewMemorySync()))
|
||||
func checkMigrationInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
|
||||
actorStore := store.ActorStore(ctx, bs)
|
||||
startTime := time.Now()
|
||||
|
||||
stateTreeV8, err := state.LoadStateTree(actorStore, v8StateRoot)
|
||||
if err != nil {
|
||||
@ -188,6 +215,29 @@ func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot
|
||||
return err
|
||||
}
|
||||
|
||||
// Load the state root.
|
||||
//var stateRoot types.StateRoot
|
||||
//if err := actorStore.Get(ctx, v9StateRoot, &stateRoot); err != nil {
|
||||
// return xerrors.Errorf("failed to decode state root: %w", err)
|
||||
//}
|
||||
//
|
||||
//actorCodeCids, err := actors.GetActorCodeIDs(actorstypes.Version9)
|
||||
//if err != nil {
|
||||
// return err
|
||||
//}
|
||||
//
|
||||
//actorTree, err := builtin.LoadTree(actorStore, stateRoot.Actors)
|
||||
//messages, err := v9.CheckStateInvariants(actorTree, epoch, actorCodeCids)
|
||||
//if err != nil {
|
||||
// return xerrors.Errorf("checking state invariants: %w", err)
|
||||
//}
|
||||
//
|
||||
//for _, message := range messages.Messages() {
|
||||
// fmt.Println("got the following error: ", message)
|
||||
//}
|
||||
|
||||
fmt.Println("completed invariant checks, took ", time.Since(startTime))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user