lotus/cmd/lotus-shed/postfind.go

124 lines
3.3 KiB
Go
Raw Permalink Normal View History

2020-10-13 03:00:29 +00:00
package main
import (
"fmt"
2020-10-13 03:53:14 +00:00
"github.com/filecoin-project/go-address"
2020-10-13 03:00:29 +00:00
"github.com/filecoin-project/go-state-types/abi"
2020-10-13 03:53:14 +00:00
"github.com/filecoin-project/go-state-types/big"
lapi "github.com/filecoin-project/lotus/api"
2020-10-13 03:00:29 +00:00
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/urfave/cli/v2"
)
var postFindCmd = &cli.Command{
Name: "post-find",
2020-10-13 03:53:14 +00:00
Description: "return addresses of all miners who have over zero power and have posted in the last day",
2020-10-13 03:00:29 +00:00
Flags: []cli.Flag{
&cli.StringFlag{
Name: "tipset",
Usage: "specify tipset state to search on",
},
2020-10-13 03:59:30 +00:00
&cli.BoolFlag{
Name: "verbose",
Usage: "get more frequent print updates",
},
2020-10-13 04:29:43 +00:00
&cli.BoolFlag{
Name: "withpower",
Usage: "only print addrs of miners with more than zero power",
},
2020-10-13 04:47:43 +00:00
&cli.IntFlag{
2020-10-13 04:49:32 +00:00
Name: "lookback",
2020-10-13 04:47:43 +00:00
Usage: "number of past epochs to search for post",
Value: 2880, //default 1 day
2020-10-13 04:49:32 +00:00
},
2020-10-13 03:00:29 +00:00
},
Action: func(c *cli.Context) error {
api, acloser, err := lcli.GetFullNodeAPI(c)
if err != nil {
return err
}
defer acloser()
ctx := lcli.ReqContext(c)
2020-10-13 03:59:30 +00:00
verbose := c.Bool("verbose")
2020-10-13 04:29:43 +00:00
withpower := c.Bool("withpower")
2020-10-13 03:00:29 +00:00
startTs, err := lcli.LoadTipSet(ctx, c, api)
2020-10-13 03:00:29 +00:00
if err != nil {
return err
}
stopEpoch := startTs.Height() - abi.ChainEpoch(c.Int("lookback"))
2020-10-13 03:59:30 +00:00
if verbose {
fmt.Printf("Collecting messages between %d and %d\n", startTs.Height(), stopEpoch)
2020-10-13 03:59:30 +00:00
}
2020-10-13 03:53:14 +00:00
// Get all messages over the last day
ts := startTs
2020-10-13 03:53:14 +00:00
msgs := make([]*types.Message, 0)
for ts.Height() > stopEpoch {
2020-10-13 03:53:14 +00:00
// Get messages on ts parent
next, err := api.ChainGetParentMessages(ctx, ts.Cids()[0])
if err != nil {
return err
}
msgs = append(msgs, messagesFromAPIMessages(next)...)
// Next ts
ts, err = api.ChainGetTipSet(ctx, ts.Parents())
if err != nil {
return err
}
2020-10-13 03:59:30 +00:00
if verbose && int64(ts.Height())%100 == 0 {
fmt.Printf("Collected messages back to height %d\n", ts.Height())
}
2020-10-13 03:53:14 +00:00
}
fmt.Printf("Loaded messages to height %d\n", ts.Height())
mAddrs, err := api.StateListMiners(ctx, startTs.Key())
2020-10-13 03:00:29 +00:00
if err != nil {
return err
}
2020-10-13 04:29:43 +00:00
minersToCheck := make(map[address.Address]struct{})
2020-10-13 03:00:29 +00:00
for _, mAddr := range mAddrs {
// if they have no power ignore. This filters out 14k inactive miners
// so we can do 100x fewer expensive message queries
2020-10-13 04:29:43 +00:00
if withpower {
power, err := api.StateMinerPower(ctx, mAddr, startTs.Key())
2020-10-13 04:29:43 +00:00
if err != nil {
return err
}
if power.MinerPower.RawBytePower.GreaterThan(big.Zero()) {
minersToCheck[mAddr] = struct{}{}
}
} else {
minersToCheck[mAddr] = struct{}{}
2020-10-13 03:00:29 +00:00
}
2020-10-13 03:53:14 +00:00
}
2020-10-13 04:38:15 +00:00
fmt.Printf("Loaded %d miners to check\n", len(minersToCheck))
2020-10-13 03:53:14 +00:00
postedMiners := make(map[address.Address]struct{})
2020-10-13 04:16:51 +00:00
for _, msg := range msgs {
2020-10-13 04:47:43 +00:00
_, shouldCheck := minersToCheck[msg.To]
2020-10-13 03:53:14 +00:00
_, seenBefore := postedMiners[msg.To]
2020-10-13 04:47:43 +00:00
if shouldCheck && !seenBefore {
2020-10-13 03:00:29 +00:00
if msg.Method == builtin.MethodsMiner.SubmitWindowedPoSt {
2020-10-13 03:53:14 +00:00
fmt.Printf("%s\n", msg.To)
2020-10-13 04:47:43 +00:00
postedMiners[msg.To] = struct{}{}
2020-10-13 03:00:29 +00:00
}
}
}
return nil
},
}
2020-10-13 03:53:14 +00:00
func messagesFromAPIMessages(apiMessages []lapi.Message) []*types.Message {
messages := make([]*types.Message, len(apiMessages))
for i, apiMessage := range apiMessages {
messages[i] = apiMessage.Message
}
return messages
}