Make pre-migration optional

This commit is contained in:
Geoff Stuart 2022-11-14 16:46:45 -05:00
parent cde4b804e3
commit 62fedfbce3
4 changed files with 90 additions and 59 deletions

View File

@ -1355,7 +1355,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut
"IsSlow": isSlow,
"IsVerySlow": isVerySlow,
"IntExit": func(i exitcode.ExitCode) int64 { return int64(i) },
"SumGas": sumGas,
"SumGas": SumGas,
"CodeStr": codeStr,
"Call": call,
"PrintTiming": func() bool { return printTiming },
@ -1423,7 +1423,7 @@ func isVerySlow(t time.Duration) bool {
return t > 50*time.Millisecond
}
func sumGas(changes []*types.GasTrace) types.GasTrace {
func SumGas(changes []*types.GasTrace) types.GasTrace {
var out types.GasTrace
for _, gc := range changes {
out.TotalGas += gc.TotalGas

View File

@ -8,14 +8,13 @@ import (
"strconv"
"text/tabwriter"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/ipfs/go-cid"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/beacon/drand"
@ -29,9 +28,15 @@ import (
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
)
var gasEstimationCmd = &cli.Command{
Name: "estimate-gas",
Description: "replay a message on the specified stateRoot and network version",
// USAGE: Sync a node, then call migrate-nv17 on some old state. Pass in the cid of the migrated state root,
// the epoch you migrated at, the network version you migrated to, and a message hash. You will be able to replay any
// message from between the migration epoch, and where your node originally synced to. Note: You may run into issues
// with nonces, or state that changed between the epoch you migrated at, and when the message was originally processed.
// This can be avoided by replaying messages from close to the migration epoch, or circumvented by using a custom
// FVM bundle.
var gasTraceCmd = &cli.Command{
Name: "trace-gas",
Description: "replay a message on the specified stateRoot and network version to get an execution trace",
ArgsUsage: "[migratedStateRootCid migrationEpoch networkVersion messageHash]",
Flags: []cli.Flag{
&cli.StringFlag{
@ -56,7 +61,7 @@ var gasEstimationCmd = &cli.Command{
return fmt.Errorf("failed to parse input: %w", err)
}
nv, err := strconv.ParseInt(cctx.Args().Get(2), 10, 64)
nv, err := strconv.ParseInt(cctx.Args().Get(2), 10, 32)
if err != nil {
return fmt.Errorf("failed to parse input: %w", err)
}
@ -131,11 +136,12 @@ var gasEstimationCmd = &cli.Command{
return err
}
tw := tabwriter.NewWriter(os.Stdout, 2, 2, 2, ' ', 0)
tw := tabwriter.NewWriter(os.Stdout, 8, 2, 2, ' ', tabwriter.AlignRight)
res, err := sm.CallAtStateAndVersion(ctx, msg, executionTs, stateRootCid, network.Version(nv))
if err != nil {
return err
}
fmt.Println("Total gas used ", res.MsgRct.GasUsed)
printInternalExecutions(0, []types.ExecutionTrace{res.ExecutionTrace}, tw)
return tw.Flush()
@ -144,10 +150,29 @@ var gasEstimationCmd = &cli.Command{
func printInternalExecutions(depth int, trace []types.ExecutionTrace, tw *tabwriter.Writer) {
if depth == 0 {
_, _ = fmt.Fprintf(tw, "depth\tFrom\tTo\tValue\tMethod\tGasUsed\tExitCode\tReturn\n")
_, _ = fmt.Fprintf(tw, "Depth\tFrom\tTo\tMethod\tTotalGas\tComputeGas\tStorageGas\t\tExitCode\n")
}
for _, im := range trace {
_, _ = fmt.Fprintf(tw, "%d\t%s\t%s\t%s\t%d\t%d\t%d\t%x\n", depth, im.Msg.From, im.Msg.To, im.Msg.Value, im.Msg.Method, im.MsgRct.GasUsed, im.MsgRct.ExitCode, im.MsgRct.Return)
sumGas := lcli.SumGas(im.GasCharges)
_, _ = fmt.Fprintf(tw, "%d\t%s\t%s\t%d\t%d\t%d\t%d\t\t%d\n", depth, truncateString(im.Msg.From.String(), 10), truncateString(im.Msg.To.String(), 10), im.Msg.Method, sumGas.TotalGas, sumGas.ComputeGas, sumGas.StorageGas, im.MsgRct.ExitCode)
printInternalExecutions(depth+1, im.Subcalls, tw)
}
}
func truncateString(str string, length int) string {
if len(str) <= length {
return str
}
truncated := ""
count := 0
for _, char := range str {
truncated += string(char)
count++
if count >= length {
break
}
}
truncated += "..."
return truncated
}

View File

@ -76,7 +76,7 @@ func main() {
msigCmd,
fip36PollCmd,
invariantsCmd,
gasEstimationCmd,
gasTraceCmd,
}
app := &cli.App{

View File

@ -53,6 +53,9 @@ var migrationsCmd = &cli.Command{
Name: "repo",
Value: "~/.lotus",
},
&cli.BoolFlag{
Name: "skip-pre-migration",
},
&cli.BoolFlag{
Name: "check-invariants",
},
@ -119,45 +122,8 @@ var migrationsCmd = &cli.Command{
return err
}
ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false)
if err != nil {
return err
}
startTime := time.Now()
err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1)
if err != nil {
return err
}
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
}
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
@ -165,18 +131,58 @@ var migrationsCmd = &cli.Command{
uncachedMigrationTime := time.Since(startTime)
if newCid1 != newCid2 {
return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1,
newCid2)
}
fmt.Println("migration height ", blk.Height-1)
fmt.Println("old cid ", blk.ParentStateRoot)
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.IsSet("skip-pre-migration") {
startTime = time.Now()
ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false)
if err != nil {
return err
}
err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1)
if err != nil {
return err
}
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
}
cachedMigrationTime := time.Since(startTime)
if newCid1 != newCid2 {
return xerrors.Errorf("got different results with and without the cache: %s, %s", newCid1,
newCid2)
}
fmt.Println("completed premigration 1, took ", preMigration1Time)
fmt.Println("completed premigration 2, took ", preMigration2Time)
fmt.Println("completed round actual (with cache), took ", cachedMigrationTime)
}
if cctx.Bool("check-invariants") {
err = checkMigrationInvariants(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1)
if err != nil {