diff --git a/cmd/lotus-sim/info.go b/cmd/lotus-sim/info.go index 9b4e9daaf..187c2236e 100644 --- a/cmd/lotus-sim/info.go +++ b/cmd/lotus-sim/info.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "io" "text/tabwriter" "time" @@ -13,6 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/actors/builtin/power" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/cmd/lotus-sim/simulation" ) func getTotalPower(ctx context.Context, sm *stmgr.StateManager, ts *types.TipSet) (power.Claim, error) { @@ -27,6 +29,48 @@ func getTotalPower(ctx context.Context, sm *stmgr.StateManager, ts *types.TipSet return state.TotalPower() } +func printInfo(ctx context.Context, sim *simulation.Simulation, out io.Writer) error { + powerNow, err := getTotalPower(ctx, sim.StateManager, sim.GetHead()) + if err != nil { + return err + } + powerStart, err := getTotalPower(ctx, sim.StateManager, sim.GetStart()) + if err != nil { + return err + } + powerGrowth := big.Sub(powerNow.RawBytePower, powerStart.RawBytePower) + + tw := tabwriter.NewWriter(out, 8, 8, 1, ' ', 0) + + head := sim.GetHead() + start := sim.GetStart() + headEpoch := head.Height() + firstEpoch := start.Height() + 1 + + headTime := time.Unix(int64(head.MinTimestamp()), 0) + startTime := time.Unix(int64(start.MinTimestamp()), 0) + duration := headTime.Sub(startTime) + + // growth rate in size/day + growthRate := big.Div( + big.Mul(powerGrowth, big.NewInt(int64(24*time.Hour))), + big.NewInt(int64(duration)), + ) + + fmt.Fprintf(tw, "Name:\t%s\n", sim.Name()) + fmt.Fprintf(tw, "Head:\t%s\n", head) + fmt.Fprintf(tw, "Last Epoch:\t%d\n", headEpoch) + fmt.Fprintf(tw, "First Epoch:\t%d\n", firstEpoch) + fmt.Fprintf(tw, "Length:\t%d\n", headEpoch-firstEpoch) + fmt.Fprintf(tw, "Date:\t%s\n", headTime) + fmt.Fprintf(tw, "Duration:\t%s\n", duration) + fmt.Fprintf(tw, "Power:\t%s\n", types.SizeStr(powerNow.RawBytePower)) + fmt.Fprintf(tw, "Power Growth:\t%s\n", types.SizeStr(powerGrowth)) + fmt.Fprintf(tw, "Power Growth Rate:\t%s/day\n", types.SizeStr(growthRate)) + fmt.Fprintf(tw, "Network Version:\t%d\n", sim.GetNetworkVersion()) + return tw.Flush() +} + var infoSimCommand = &cli.Command{ Name: "info", Description: "Output information about the simulation.", @@ -41,45 +85,6 @@ var infoSimCommand = &cli.Command{ if err != nil { return err } - - powerNow, err := getTotalPower(cctx.Context, sim.StateManager, sim.GetHead()) - if err != nil { - return err - } - powerStart, err := getTotalPower(cctx.Context, sim.StateManager, sim.GetStart()) - if err != nil { - return err - } - powerGrowth := big.Sub(powerNow.RawBytePower, powerStart.RawBytePower) - - tw := tabwriter.NewWriter(cctx.App.Writer, 8, 8, 0, ' ', 0) - - head := sim.GetHead() - start := sim.GetStart() - headEpoch := head.Height() - firstEpoch := start.Height() + 1 - - headTime := time.Unix(int64(head.MinTimestamp()), 0) - startTime := time.Unix(int64(start.MinTimestamp()), 0) - duration := headTime.Sub(startTime) - - // growth rate in size/day - growthRate := big.Div( - big.Mul(powerGrowth, big.NewInt(int64(24*time.Hour))), - big.NewInt(int64(duration)), - ) - - fmt.Fprintf(tw, "Name:\t%s\n", sim.Name()) - fmt.Fprintf(tw, "Head:\t%s\n", head) - fmt.Fprintf(tw, "Last Epoch:\t%d\n", headEpoch) - fmt.Fprintf(tw, "First Epoch:\t%d\n", firstEpoch) - fmt.Fprintf(tw, "Length:\t%d\n", headEpoch-firstEpoch) - fmt.Fprintf(tw, "Date:\t%s\n", headTime) - fmt.Fprintf(tw, "Duration:\t%s\n", duration) - fmt.Fprintf(tw, "Power:\t%s\n", types.SizeStr(powerNow.RawBytePower)) - fmt.Fprintf(tw, "Power Growth:\t%s\n", types.SizeStr(powerGrowth)) - fmt.Fprintf(tw, "Power Growth Rate:\t%s/day\n", types.SizeStr(growthRate)) - fmt.Fprintf(tw, "Network Version:\t%d\n", sim.GetNetworkVersion()) - return tw.Flush() + return printInfo(cctx.Context, sim, cctx.App.Writer) }, } diff --git a/cmd/lotus-sim/run.go b/cmd/lotus-sim/run.go index f696243fa..388b8f763 100644 --- a/cmd/lotus-sim/run.go +++ b/cmd/lotus-sim/run.go @@ -2,6 +2,8 @@ package main import ( "fmt" + "os" + "os/signal" "syscall" "github.com/urfave/cli/v2" @@ -36,12 +38,29 @@ var runSimCommand = &cli.Command{ } fmt.Fprintln(cctx.App.Writer, "running simulation") targetEpochs := cctx.Int("epochs") + + ch := make(chan os.Signal, 1) + signal.Notify(ch, syscall.SIGUSR1) + defer signal.Stop(ch) + for i := 0; targetEpochs == 0 || i < targetEpochs; i++ { ts, err := sim.Step(cctx.Context) if err != nil { return err } + fmt.Fprintf(cctx.App.Writer, "advanced to %d %s\n", ts.Height(), ts.Key()) + + // Print + select { + case <-ch: + if err := printInfo(cctx.Context, sim, cctx.App.Writer); err != nil { + fmt.Fprintf(cctx.App.ErrWriter, "ERROR: failed to print info: %s\n", err) + } + case <-cctx.Context.Done(): + return cctx.Err() + default: + } } fmt.Fprintln(cctx.App.Writer, "simulation done") return err