From 2f4582147a81fe5f72b73cbfd70f47171548d1b0 Mon Sep 17 00:00:00 2001 From: jennijuju Date: Tue, 27 Oct 2020 18:26:32 -0400 Subject: [PATCH] Add `termination-estimate` to get an estimation for how much a termination penalty will be: - Usage example: `./lotus-shed sectors termation-estimate 5 8 10`. --- cmd/lotus-shed/sectors.go | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/cmd/lotus-shed/sectors.go b/cmd/lotus-shed/sectors.go index 2e78469fa3e..64f3faf799b 100644 --- a/cmd/lotus-shed/sectors.go +++ b/cmd/lotus-shed/sectors.go @@ -25,6 +25,7 @@ var sectorsCmd = &cli.Command{ Flags: []cli.Flag{}, Subcommands: []*cli.Command{ terminateSectorCmd, + terminateSectorPenaltyEstimationCmd, }, } @@ -131,3 +132,101 @@ var terminateSectorCmd = &cli.Command{ return nil }, } + +func findPenaltyInInternalExecutions(prefix string, trace []types.ExecutionTrace) { + for _, im := range trace { + if im.Msg.To.String() == "f099" /*Burn actor*/ { + fmt.Printf("Estimated termination penalty: %s attoFIL\n", im.Msg.Value) + return + } + findPenaltyInInternalExecutions(prefix+"\t", im.Subcalls) + } +} + +var terminateSectorPenaltyEstimationCmd = &cli.Command{ + Name: "termination-estimate", + Usage: "Estimate the termination penalty", + ArgsUsage: "[sectorNum1 sectorNum2 ...]", + Action: func(cctx *cli.Context) error { + if cctx.Args().Len() < 1 { + return fmt.Errorf("at least one sector must be specified") + } + + nodeApi, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + + api, acloser, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer acloser() + + ctx := lcli.ReqContext(cctx) + + maddr, err := api.ActorAddress(ctx) + if err != nil { + return err + } + + mi, err := nodeApi.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return err + } + + terminationDeclarationParams := []miner2.TerminationDeclaration{} + + for _, sn := range cctx.Args().Slice() { + sectorNum, err := strconv.ParseUint(sn, 10, 64) + if err != nil { + return fmt.Errorf("could not parse sector number: %w", err) + } + + sectorbit := bitfield.New() + sectorbit.Set(sectorNum) + + loca, err := nodeApi.StateSectorPartition(ctx, maddr, abi.SectorNumber(sectorNum), types.EmptyTSK) + if err != nil { + return fmt.Errorf("get state sector partition %s", err) + } + + para := miner2.TerminationDeclaration{ + Deadline: loca.Deadline, + Partition: loca.Partition, + Sectors: sectorbit, + } + + terminationDeclarationParams = append(terminationDeclarationParams, para) + } + + terminateSectorParams := &miner2.TerminateSectorsParams{ + Terminations: terminationDeclarationParams, + } + + sp, err := actors.SerializeParams(terminateSectorParams) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) + } + + msg := &types.Message{ + From: mi.Owner, + To: maddr, + Method: miner.Methods.TerminateSectors, + + Value: big.Zero(), + Params: sp, + } + + //TODO: 4667 add an option to give a more precise estimation with pending termination penalty excluded + + invocResult, err := nodeApi.StateCall(ctx, msg, types.TipSetKey{}) + if err != nil { + return xerrors.Errorf("fail to state call: %w", err) + } + + findPenaltyInInternalExecutions("\t", invocResult.ExecutionTrace.Subcalls) + return nil + }, +}