From 977e302e0ce4892cd55062b77a608334c4337b05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Fri, 25 Mar 2022 19:02:53 +0000 Subject: [PATCH] lotus-shed: add command to compute state over a range of tipsets. --- cmd/lotus-shed/chain.go | 61 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/chain.go b/cmd/lotus-shed/chain.go index 05abeff8f..efbbd3b62 100644 --- a/cmd/lotus-shed/chain.go +++ b/cmd/lotus-shed/chain.go @@ -3,8 +3,9 @@ package main import ( "fmt" - lcli "github.com/filecoin-project/lotus/cli" "github.com/urfave/cli/v2" + + lcli "github.com/filecoin-project/lotus/cli" ) var chainCmd = &cli.Command{ @@ -12,6 +13,7 @@ var chainCmd = &cli.Command{ Usage: "chain-related utilities", Subcommands: []*cli.Command{ chainNullTsCmd, + computeStateRangeCmd, }, } @@ -47,3 +49,60 @@ var chainNullTsCmd = &cli.Command{ } }, } + +var computeStateRangeCmd = &cli.Command{ + Name: "compute-state-range", + Usage: "forces the computation of a range of tipsets", + ArgsUsage: "[START_TIPSET_REF] [END_TIPSET_REF]", + Action: func(cctx *cli.Context) error { + if cctx.NArg() != 2 { + return fmt.Errorf("expected two arguments: a start and an end tipset") + } + + api, closer, err := lcli.GetFullNodeAPI(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + startTs, err := lcli.ParseTipSetRef(ctx, api, cctx.Args().First()) + if err != nil { + return err + } + + endTs, err := lcli.ParseTipSetRef(ctx, api, cctx.Args().Get(1)) + if err != nil { + return err + } + + fmt.Printf("computing tipset at height %d (start)\n", startTs.Height()) + if _, err := api.StateCompute(ctx, startTs.Height(), nil, startTs.Key()); err != nil { + return err + } + + for height := startTs.Height() + 1; height < endTs.Height(); height++ { + fmt.Printf("computing tipset at height %d\n", height) + + // The fact that the tipset lookup method takes a tipset is rather annoying. + // This is because we walk back from the supplied tipset (which could be the HEAD) + // to locate the desired one. + ts, err := api.ChainGetTipSetByHeight(ctx, height, endTs.Key()) + if err != nil { + return err + } + + if _, err := api.StateCompute(ctx, height, nil, ts.Key()); err != nil { + return err + } + } + + fmt.Printf("computing tipset at height %d (end)\n", endTs.Height()) + if _, err := api.StateCompute(ctx, endTs.Height(), nil, endTs.Key()); err != nil { + return err + } + + return nil + }, +}