Merge pull request #9525 from filecoin-project/asr/premigrations

feat: state: add a second premigration for nv17
This commit is contained in:
Aayush Rajasekaran 2022-10-20 13:57:25 -04:00 committed by GitHub
commit 26ba489746
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 227 additions and 15 deletions

View File

@ -197,8 +197,13 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
Migration: UpgradeActorsV9, Migration: UpgradeActorsV9,
PreMigrations: []stmgr.PreMigration{{ PreMigrations: []stmgr.PreMigration{{
PreMigration: PreUpgradeActorsV9, PreMigration: PreUpgradeActorsV9,
StartWithin: 180, StartWithin: 240,
DontStartWithin: 60, DontStartWithin: 60,
StopWithin: 20,
}, {
PreMigration: PreUpgradeActorsV9,
StartWithin: 15,
DontStartWithin: 10,
StopWithin: 5, StopWithin: 5,
}}, }},
Expensive: true, Expensive: true,

View File

@ -1,20 +1,177 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"io"
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"golang.org/x/xerrors" "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" "github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli" lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/node/repo"
) )
var diffCmd = &cli.Command{ var diffCmd = &cli.Command{
Name: "diff", Name: "diff",
Usage: "diff state objects", Usage: "diff state objects",
Subcommands: []*cli.Command{diffStateTrees}, 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{ var diffStateTrees = &cli.Command{

View File

@ -52,6 +52,9 @@ var migrationsCmd = &cli.Command{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
}, },
&cli.BoolFlag{
Name: "check-invariants",
},
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
ctx := context.TODO() ctx := context.TODO()
@ -115,7 +118,7 @@ var migrationsCmd = &cli.Command{
return err 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 { if err != nil {
return err return err
} }
@ -127,41 +130,65 @@ var migrationsCmd = &cli.Command{
return err 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() startTime = time.Now()
newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs) newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
if err != nil { if err != nil {
return err 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) newCid2, err := filcns.UpgradeActorsV9(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
if err != nil { if err != nil {
return err 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 { if newCid1 != newCid2 {
return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1, return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1,
newCid2) newCid2)
} }
err = checkStateInvariants(ctx, blk.ParentStateRoot, newCid1, bs) 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 { if err != nil {
return err return err
} }
}
return nil return nil
}, },
} }
func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot cid.Cid, bs blockstore.Blockstore) error { func checkMigrationInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
actorStore := store.ActorStore(ctx, blockstore.NewTieredBstore(bs, blockstore.NewMemorySync())) actorStore := store.ActorStore(ctx, bs)
startTime := time.Now()
stateTreeV8, err := state.LoadStateTree(actorStore, v8StateRoot) stateTreeV8, err := state.LoadStateTree(actorStore, v8StateRoot)
if err != nil { if err != nil {
@ -188,6 +215,29 @@ func checkStateInvariants(ctx context.Context, v8StateRoot cid.Cid, v9StateRoot
return err 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 return nil
} }