lotus/cmd/lotus-shed/nonce-fix.go
2020-03-10 01:28:59 +01:00

110 lines
2.0 KiB
Go

package main
import (
"fmt"
"math"
"github.com/filecoin-project/go-address"
"gopkg.in/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")
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: types.NewInt(1000),
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
},
}