package main import ( "fmt" "math" "github.com/filecoin-project/go-address" "github.com/urfave/cli/v2" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" ) var noncefix = &cli.Command{ Name: "noncefix", Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", EnvVars: []string{"LOTUS_PATH"}, Hidden: true, Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME }, &cli.Uint64Flag{ Name: "start", }, &cli.Uint64Flag{ Name: "end", }, &cli.StringFlag{ Name: "addr", }, &cli.BoolFlag{ Name: "auto", }, }, Action: func(cctx *cli.Context) error { api, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { return err } defer closer() ctx := lcli.ReqContext(cctx) addr, err := address.NewFromString(cctx.String("addr")) if err != nil { return err } start := cctx.Uint64("start") end := cctx.Uint64("end") if end == 0 { end = math.MaxUint64 } if cctx.Bool("auto") { a, err := api.StateGetActor(ctx, addr, types.EmptyTSK) if err != nil { return err } start = a.Nonce msgs, err := api.MpoolPending(ctx, types.EmptyTSK) if err != nil { return err } for _, msg := range msgs { if msg.Message.From != addr { continue } if msg.Message.Nonce < start { continue // past } if msg.Message.Nonce < end { end = msg.Message.Nonce } } } if end == math.MaxUint64 { fmt.Println("No nonce gap found or no --end flag specified") return nil } fmt.Printf("Creating %d filler messages (%d ~ %d)\n", end-start, start, end) for i := start; i < end; i++ { msg := &types.Message{ From: addr, To: addr, Value: types.NewInt(1), GasLimit: 100_000_000, GasPrice: types.NewInt(1), Nonce: i, } smsg, err := api.WalletSignMessage(ctx, addr, msg) if err != nil { return err } _, err = api.MpoolPush(ctx, smsg) if err != nil { return err } } return nil }, }